auth-backend: make key duration configurable

This commit is contained in:
Patrik Oldsberg
2020-06-20 00:35:01 +02:00
parent 55faf713c3
commit c72056eb29
3 changed files with 20 additions and 11 deletions
@@ -25,8 +25,6 @@ const migrationsDir = path.resolve(
'../migrations',
);
const KEY_DURATION_MS = 3600 * 1000;
const TABLE = 'signing_keys';
type Row = {
@@ -38,28 +36,32 @@ type Row = {
type Options = {
logger: Logger;
database: Knex;
/** Expiration time of signing keys in seconds */
keyDuration: number;
};
export class DatabaseKeyStore {
static async create(options: Options): Promise<DatabaseKeyStore> {
const { logger, database } = options;
const { database } = options;
await database.migrate.latest({
directory: migrationsDir,
});
return new DatabaseKeyStore({ logger, database });
return new DatabaseKeyStore(options);
}
private readonly logger: Logger;
private readonly database: Knex;
private readonly keyDuration: number;
private removingExpiredRows: boolean = false;
private constructor(options: Options) {
const { logger, database } = options;
const { logger, database, keyDuration } = options;
this.database = database;
this.keyDuration = keyDuration;
this.logger = logger.child({ service: 'key-store' });
}
@@ -90,7 +92,7 @@ export class DatabaseKeyStore {
for (const row of rows) {
const createdAt = utc(row.created_at);
const expireAt = createdAt.add(3 * KEY_DURATION_MS, 'ms');
const expireAt = createdAt.add(3 * this.keyDuration, 'seconds');
const isExpired = expireAt.isBefore();
if (isExpired) {
@@ -19,26 +19,30 @@ import { JSONWebKey, JWK, JWS } from 'jose';
import { Logger } from 'winston';
import { v4 as uuid } from 'uuid';
const KEY_DURATION_MS = 3600 * 1000;
type Options = {
issuer: string;
logger: Logger;
/** Value of the issuer claim in issued tokens */
issuer: string;
/** Key store used for storing signing keys */
keyStore: KeyStore;
/** Expiration time of signing keys in seconds */
keyDuration: number;
};
export class TokenFactory implements TokenIssuer {
private readonly issuer: string;
private readonly logger: Logger;
private readonly keyStore: KeyStore;
private readonly keyDuration: number;
private keyExpiry?: number;
private privateKeyPromise?: Promise<JSONWebKey>;
constructor(options: Options) {
const { issuer, logger, keyStore } = options;
const { issuer, logger, keyStore, keyDuration } = options;
this.issuer = issuer;
this.keyStore = keyStore;
this.keyDuration = keyDuration;
this.logger = logger.child({ service: 'issuer' });
}
@@ -68,7 +72,7 @@ export class TokenFactory implements TokenIssuer {
delete this.privateKeyPromise;
}
this.keyExpiry = Date.now() + KEY_DURATION_MS;
this.keyExpiry = Date.now() + this.keyDuration * 1000;
const promise = (async () => {
const key = await JWK.generate('EC', 'P-256', {
use: 'sig',
@@ -37,15 +37,18 @@ export async function createRouter(
const logger = options.logger.child({ plugin: 'auth' });
const baseUrl = `${options.config.getString('backend.baseUrl')}/auth`;
const keyDuration = 3600;
const keyStore = await DatabaseKeyStore.create({
database: options.database,
logger,
keyDuration,
});
const issuer = new TokenFactory({
issuer: baseUrl,
keyStore,
logger,
keyDuration,
});
router.use(cookieParser());