This commit is contained in:
@ -21,7 +21,6 @@ interface AccessResult {
|
||||
refresh_token_id?: string;
|
||||
}
|
||||
|
||||
|
||||
interface AccessResponse {
|
||||
token_type: string;
|
||||
access_token: string;
|
||||
@ -69,15 +68,20 @@ class AuthRequest {
|
||||
this.response.setHeader ('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public allow_access ({
|
||||
public async allow_access ({
|
||||
access_token_expires_in,
|
||||
include_refresh_token,
|
||||
refresh_token_expires_in,
|
||||
data
|
||||
}: AccessSettings): AccessResult {
|
||||
}: AccessSettings): Promise<AccessResult> {
|
||||
this.default_header ();
|
||||
|
||||
const at = auth.sign ('access_token', access_token_expires_in, { data });
|
||||
const at = await auth.sign (
|
||||
'access_token',
|
||||
access_token_expires_in,
|
||||
|
||||
{ data }
|
||||
);
|
||||
const result: AccessResult = { access_token_id: at.id };
|
||||
|
||||
const res: AccessResponse = {
|
||||
@ -96,7 +100,7 @@ class AuthRequest {
|
||||
if (include_refresh_token) {
|
||||
if (typeof refresh_token_expires_in !== 'number')
|
||||
throw new Error ('no expiry time defined for refresh tokens');
|
||||
const rt = auth.sign (
|
||||
const rt = await auth.sign (
|
||||
'refresh_token',
|
||||
refresh_token_expires_in,
|
||||
{ data }
|
||||
@ -111,14 +115,14 @@ class AuthRequest {
|
||||
return result;
|
||||
}
|
||||
|
||||
public allow_part (
|
||||
public async allow_part (
|
||||
part_token_expires_in: number,
|
||||
next_module: string,
|
||||
data?: Record<string, unknown>
|
||||
): string {
|
||||
): Promise<string> {
|
||||
this.default_header ();
|
||||
|
||||
const pt = auth.sign (
|
||||
const pt = await auth.sign (
|
||||
'part_token',
|
||||
part_token_expires_in,
|
||||
{ next_module, data }
|
||||
|
@ -79,13 +79,13 @@ class Authority {
|
||||
return result;
|
||||
}
|
||||
|
||||
public sign (
|
||||
public async sign (
|
||||
type: TokenType,
|
||||
valid_for: number,
|
||||
options?: SignatureOptions
|
||||
): SignatureResult {
|
||||
): Promise<SignatureResult> {
|
||||
const time = Date.now ();
|
||||
const key = keystore.get_key (time / 1000, valid_for);
|
||||
const key = await keystore.get_sign_key (time / 1000, valid_for);
|
||||
const attributes = {
|
||||
id: create_salt (),
|
||||
iat: time,
|
||||
|
@ -5,14 +5,24 @@
|
||||
* Created by Timo Hocker <timo@scode.ovh>, December 2020
|
||||
*/
|
||||
|
||||
import { create_salt } from '@sapphirecode/crypto-helper';
|
||||
import { generate_keypair } from '@sapphirecode/crypto-helper';
|
||||
|
||||
interface Keypair {
|
||||
private_key: string;
|
||||
public_key: string;
|
||||
}
|
||||
|
||||
interface Key {
|
||||
key: string;
|
||||
key: Keypair;
|
||||
valid_until: number;
|
||||
timeout: NodeJS.Timeout;
|
||||
}
|
||||
|
||||
function get_index (iat: number): string {
|
||||
return Math.floor (iat / 60)
|
||||
.toFixed (0);
|
||||
}
|
||||
|
||||
class KeyStore {
|
||||
private _keys: Record<string, Key> = {};
|
||||
|
||||
@ -22,38 +32,46 @@ class KeyStore {
|
||||
}, (valid_for + 5) * 1000);
|
||||
}
|
||||
|
||||
public get_key (iat: number, valid_for = 0): string {
|
||||
const index = Math.floor (iat / 60)
|
||||
.toFixed (0);
|
||||
public async get_sign_key (iat: number, valid_for: number): Promise<string> {
|
||||
const index = get_index (iat);
|
||||
|
||||
if (valid_for <= 0)
|
||||
throw new Error ('cannot create infinitely valid key');
|
||||
|
||||
if ((iat + 1) * 1000 < (new Date)
|
||||
.getTime ())
|
||||
throw new Error ('cannot access already expired keys');
|
||||
|
||||
const valid_until = (new Date)
|
||||
.getTime () + (valid_for * 1000);
|
||||
|
||||
if (typeof this._keys[index] !== 'undefined') {
|
||||
const key = this._keys[index];
|
||||
if (valid_for !== 0 && key.valid_until < valid_until) {
|
||||
if (key.valid_until < valid_until) {
|
||||
clearTimeout (key.timeout);
|
||||
key.timeout = this.set_timeout (index, valid_for);
|
||||
key.valid_until = valid_until;
|
||||
}
|
||||
return key.key;
|
||||
return key.key.private_key;
|
||||
}
|
||||
|
||||
if (valid_for !== 0) {
|
||||
if ((iat + 1) * 1000 < (new Date)
|
||||
.getTime ())
|
||||
throw new Error ('cannot create already expired keys');
|
||||
this._keys[index] = {
|
||||
key: await generate_keypair (),
|
||||
timeout: this.set_timeout (index, valid_for),
|
||||
valid_until
|
||||
};
|
||||
|
||||
this._keys[index] = {
|
||||
key: create_salt (),
|
||||
timeout: this.set_timeout (index, valid_for),
|
||||
valid_until
|
||||
};
|
||||
return this._keys[index].key.private_key;
|
||||
}
|
||||
|
||||
return this._keys[index].key;
|
||||
}
|
||||
public get_key (iat: number): string {
|
||||
const index = get_index (iat);
|
||||
|
||||
throw new Error ('key could not be found');
|
||||
if (typeof this._keys[index] === 'undefined')
|
||||
throw new Error ('key could not be found');
|
||||
|
||||
const key = this._keys[index];
|
||||
return key.key.public_key;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user