backend-app-api: update DatabaseKeyStore to store expiration as string

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-04-05 16:04:37 +02:00
parent 4f2aafb86c
commit ae38fbb6b8
3 changed files with 6 additions and 24 deletions
@@ -32,8 +32,9 @@ exports.up = async function up(knex) {
table.text('key').notNullable().comment('JSON serialized public key');
// Expiration is stored as a string for simplicity, all checks are done client-side
table
.timestamp('expires_at')
.string('expires_at')
.notNullable()
.comment('The time that the key expires');
},
@@ -118,7 +118,7 @@ describe('DatabaseKeyStore', () => {
key: testKey,
expiresAt: new Date(NaN),
}),
).rejects.toThrow('Failed to format public key expiration date');
).rejects.toThrow('Invalid time value');
});
});
});
@@ -28,7 +28,7 @@ export const TABLE = 'backstage_backend_public_keys__keys';
type Row = {
id: string;
key: string;
expires_at: string | Date; // Needs parsing to handle different DB implementations
expires_at: string;
};
export function applyDatabaseMigrations(knex: Knex): Promise<void> {
@@ -68,14 +68,10 @@ export class DatabaseKeyStore implements KeyStore {
key: JsonObject & { kid: string };
expiresAt: Date;
}) {
const expiresAt = DateTime.fromJSDate(options.expiresAt).toSQL();
if (!expiresAt) {
throw new Error('Failed to format public key expiration date');
}
await this.client<Row>(TABLE).insert({
id: options.key.kid,
key: JSON.stringify(options.key),
expires_at: expiresAt,
expires_at: options.expiresAt.toISOString(),
});
}
@@ -84,7 +80,7 @@ export class DatabaseKeyStore implements KeyStore {
const keys = rows.map(row => ({
id: row.id,
key: JSON.parse(row.key),
expiresAt: this.#parseDate(row.expires_at),
expiresAt: new Date(row.expires_at),
}));
const validKeys = [];
@@ -120,19 +116,4 @@ export class DatabaseKeyStore implements KeyStore {
return { keys: validKeys };
}
#parseDate(date: string | Date) {
const parsedDate =
typeof date === 'string'
? DateTime.fromSQL(date, { zone: 'UTC' })
: DateTime.fromJSDate(date);
if (!parsedDate.isValid) {
throw new Error(
`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`,
);
}
return parsedDate.toJSDate();
}
}