/* * 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 , 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 { const log = logger.extend ('verify'); log ('verifying token'); const result: VerificationResult = { authorized: false, valid: false, type: 'none', id: '' }; const data = await verify_signature_get_info ( key, async (info) => { try { return await keystore.get_key (info.iat / 1000, info.iss); } catch { return ''; } }, (info) => info.valid_for * 1000 ); if (data === null) { log ('token invalid'); result.error = 'invalid signature'; return result; } result.id = data.id; result.type = data.type; log ('parsing token %s %s', result.type, result.id); if (!(await blacklist.is_valid (data.id))) { log ('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; log ( 'valid %s; targeting module %s', result.type, result.next_module ); return result; } public async sign ( type: TokenType, valid_for: number, options?: SignatureOptions ): Promise { const log = logger.extend ('sign'); log ('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); log ('created token %s', attributes.id); return { id: attributes.id, signature }; } } const auth = (new Authority); export { TokenType, VerificationResult, SignatureResult, SignatureOptions, Authority }; export default auth;