auth-server-helper/lib/Authority.ts
Timo Hocker 1009a9b8d5
Some checks failed
continuous-integration/drone/push Build is failing
catch key error
2022-08-10 11:08:14 +02:00

129 lines
2.8 KiB
TypeScript

/*
* Copyright (C) Sapphirecode - All Rights Reserved
* This file is part of Auth-Server-Helper which is released under MIT.
* See file 'LICENSE' for full license details.
* Created by Timo Hocker <timo@scode.ovh>, December 2020
*/
import {
create_salt,
sign_object,
verify_signature_get_info
} from '@sapphirecode/crypto-helper';
import keystore from './KeyStore';
import blacklist from './Blacklist';
import { debug } from './debug';
const logger = debug ('authority');
// eslint-disable-next-line no-shadow
type TokenType = 'access_token' | 'none' | 'part_token' | 'refresh_token'
interface VerificationResult {
authorized: boolean;
valid: boolean;
type: TokenType;
id: string;
next_module?: string;
data?: unknown;
error?: string;
}
interface SignatureResult {
signature: string;
id: string;
}
interface SignatureOptions
{
data?: unknown
next_module?: string
}
class Authority {
public async verify (key: string): Promise<VerificationResult> {
logger ('verifying token');
const result: VerificationResult = {
authorized: false,
valid: false,
type: 'none',
id: ''
};
const data = await verify_signature_get_info (
key,
(info) => {
try {
return await keystore.get_key (info.iat / 1000, info.iss);
}
catch {
return '';
}
},
(info) => info.valid_for * 1000
);
if (data === null) {
logger ('token invalid');
result.error = 'invalid signature';
return result;
}
result.id = data.id;
result.type = data.type;
logger ('parsing token %s %s', result.type, result.id);
if (!blacklist.is_valid (data.id)) {
logger ('token is blacklisted');
result.error = 'blacklisted';
return result;
}
result.valid = true;
result.authorized = result.type === 'access_token';
result.next_module = data.next_module;
result.data = data.obj;
logger (
'valid %s; targeting module %s',
result.type,
result.next_module
);
return result;
}
public async sign (
type: TokenType,
valid_for: number,
options?: SignatureOptions
): Promise<SignatureResult> {
logger ('signing new %s', type);
const time = Date.now ();
const key = await keystore.get_sign_key (time / 1000, valid_for);
const attributes = {
id: create_salt (),
iat: time,
iss: keystore.instance_id,
type,
valid_for,
next_module: options?.next_module
};
const signature = sign_object (options?.data, key, attributes);
logger ('created token %s', attributes.id);
return { id: attributes.id, signature };
}
}
const auth = (new Authority);
export {
TokenType,
VerificationResult,
SignatureResult,
SignatureOptions,
Authority
};
export default auth;