Use JS Date instead of Datetime

This commit is contained in:
Nils Streijffert
2021-02-11 10:16:34 +01:00
parent 529c8501b8
commit 636c70ac91
5 changed files with 23 additions and 13 deletions
@@ -16,6 +16,7 @@
import Knex from 'knex';
import { DatabaseKeyStore } from './DatabaseKeyStore';
import { DateTime } from 'luxon'
function createDB() {
const knex = Knex({
@@ -51,7 +52,7 @@ describe('DatabaseKeyStore', () => {
const { items } = await store.listKeys();
expect(items).toEqual([{ createdAt: expect.anything(), key }]);
expect(
Math.abs(items[0].createdAt.diffNow('seconds').seconds),
Math.abs(DateTime.fromJSDate(items[0].createdAt).diffNow('seconds').seconds),
).toBeLessThan(10);
});
@@ -66,9 +66,7 @@ export class DatabaseKeyStore implements KeyStore {
return {
items: rows.map(row => ({
key: JSON.parse(row.key),
createdAt: DateTime.fromSQL((row.created_at as unknown) as string, {
zone: 'UTC',
}),
createdAt: parseDate(row.created_at),
})),
};
}
@@ -77,3 +75,15 @@ export class DatabaseKeyStore implements KeyStore {
await this.database(TABLE).delete().whereIn('kid', kids);
}
}
const parseDate = (date: string | Date) => {
const parsedDate = typeof date === 'string' ? DateTime.fromSQL(date, {locale: 'UTC'}) : DateTime.fromJSDate(date)
if (!parsedDate.isValid) {
throw new Error(
`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`,
);
}
return parsedDate.toJSDate()
}
@@ -20,12 +20,12 @@ import { DateTime } from 'luxon';
export class MemoryKeyStore implements KeyStore {
private readonly keys = new Map<
string,
{ createdAt: DateTime; key: string }
{ createdAt: Date; key: string }
>();
async addKey(key: AnyJWK): Promise<void> {
this.keys.set(key.kid, {
createdAt: DateTime.utc(),
createdAt: DateTime.utc().toJSDate(),
key: JSON.stringify(key),
});
}
@@ -52,7 +52,7 @@ export class TokenFactory implements TokenIssuer {
private readonly keyStore: KeyStore;
private readonly keyDurationSeconds: number;
private keyExpiry?: DateTime;
private keyExpiry?: Date;
private privateKeyPromise?: Promise<JSONWebKey>;
constructor(options: Options) {
@@ -90,7 +90,7 @@ export class TokenFactory implements TokenIssuer {
for (const key of keys) {
// Allow for a grace period of another full key duration before we remove the keys from the database
const expireAt = key.createdAt.plus({
const expireAt = DateTime.fromJSDate(key.createdAt).plus({
seconds: 3 * this.keyDurationSeconds,
});
if (expireAt < DateTime.local()) {
@@ -119,16 +119,16 @@ export class TokenFactory implements TokenIssuer {
private async getKey(): Promise<JSONWebKey> {
// Make sure that we only generate one key at a time
if (this.privateKeyPromise) {
if (this.keyExpiry && this.keyExpiry > DateTime.local()) {
if (this.keyExpiry && DateTime.fromJSDate(this.keyExpiry) > DateTime.local()) {
return this.privateKeyPromise;
}
this.logger.info(`Signing key has expired, generating new key`);
delete this.privateKeyPromise;
}
this.keyExpiry = DateTime.local().plus({
this.keyExpiry = DateTime.utc().plus({
seconds: this.keyDurationSeconds,
});
}).toJSDate();
const promise = (async () => {
// This generates a new signing key to be used to sign tokens until the next key rotation
const key = await JWK.generate('EC', 'P-256', {
+1 -2
View File
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { DateTime } from 'luxon';
/** Represents any form of serializable JWK */
export interface AnyJWK extends Record<string, string> {
@@ -53,7 +52,7 @@ export type TokenIssuer = {
*/
export type StoredKey = {
key: AnyJWK;
createdAt: DateTime;
createdAt: Date;
};
/**