Port moment to luxon
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
import Knex from 'knex';
|
||||
import moment from 'moment';
|
||||
import { DatabaseKeyStore } from './DatabaseKeyStore';
|
||||
|
||||
function createDB() {
|
||||
@@ -51,7 +50,7 @@ describe('DatabaseKeyStore', () => {
|
||||
|
||||
const { items } = await store.listKeys();
|
||||
expect(items).toEqual([{ createdAt: expect.anything(), key }]);
|
||||
expect(Math.abs(items[0].createdAt.diff(moment(), 's'))).toBeLessThan(10);
|
||||
expect(Math.abs(items[0].createdAt.diffNow('seconds').seconds)).toBeLessThan(10);
|
||||
});
|
||||
|
||||
it('should remove stored keys', async () => {
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
*/
|
||||
|
||||
import Knex from 'knex';
|
||||
import { utc } from 'moment';
|
||||
import { resolvePackagePath } from '@backstage/backend-common';
|
||||
import { AnyJWK, KeyStore, StoredKey } from './types';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
const migrationsDir = resolvePackagePath(
|
||||
'@backstage/plugin-auth-backend',
|
||||
@@ -62,12 +62,11 @@ export class DatabaseKeyStore implements KeyStore {
|
||||
|
||||
async listKeys(): Promise<{ items: StoredKey[] }> {
|
||||
const rows = await this.database<Row>(TABLE).select();
|
||||
|
||||
return {
|
||||
items: rows.map(row => ({
|
||||
key: JSON.parse(row.key),
|
||||
createdAt: utc(row.created_at),
|
||||
})),
|
||||
key: JSON.parse(row.key),
|
||||
createdAt: DateTime.fromFormat(row.created_at, 'yyyy-MM-dd HH:mm:ss', {zone: 'UTC'}),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -14,18 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { utc } from 'moment';
|
||||
import { KeyStore, AnyJWK, StoredKey } from './types';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
export class MemoryKeyStore implements KeyStore {
|
||||
private readonly keys = new Map<
|
||||
string,
|
||||
{ createdAt: moment.Moment; key: string }
|
||||
{ createdAt: DateTime; key: string }
|
||||
>();
|
||||
|
||||
async addKey(key: AnyJWK): Promise<void> {
|
||||
this.keys.set(key.kid, {
|
||||
createdAt: utc(),
|
||||
createdAt: DateTime.local().toUTC(),
|
||||
key: JSON.stringify(key),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import { TokenIssuer, TokenParams, KeyStore, AnyJWK } from './types';
|
||||
import { JSONWebKey, JWK, JWS } from 'jose';
|
||||
import { Logger } from 'winston';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
const MS_IN_S = 1000;
|
||||
|
||||
@@ -52,7 +52,7 @@ export class TokenFactory implements TokenIssuer {
|
||||
private readonly keyStore: KeyStore;
|
||||
private readonly keyDurationSeconds: number;
|
||||
|
||||
private keyExpiry?: moment.Moment;
|
||||
private keyExpiry?: DateTime;
|
||||
private privateKeyPromise?: Promise<JSONWebKey>;
|
||||
|
||||
constructor(options: Options) {
|
||||
@@ -90,8 +90,8 @@ 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.add(3 * this.keyDurationSeconds, 's');
|
||||
if (expireAt.isBefore()) {
|
||||
const expireAt = key.createdAt.plus({ seconds: 3 * this.keyDurationSeconds });
|
||||
if (expireAt < DateTime.local()) {
|
||||
expiredKeys.push(key);
|
||||
} else {
|
||||
validKeys.push(key);
|
||||
@@ -115,16 +115,16 @@ export class TokenFactory implements TokenIssuer {
|
||||
}
|
||||
|
||||
private async getKey(): Promise<JSONWebKey> {
|
||||
// Make sure that we only generate one key at a time
|
||||
// Make sure that we only generate one key at a time¨
|
||||
if (this.privateKeyPromise) {
|
||||
if (this.keyExpiry?.isAfter()) {
|
||||
if (this.keyExpiry > DateTime.local()) {
|
||||
return this.privateKeyPromise;
|
||||
}
|
||||
this.logger.info(`Signing key has expired, generating new key`);
|
||||
delete this.privateKeyPromise;
|
||||
}
|
||||
|
||||
this.keyExpiry = moment().add(this.keyDurationSeconds, 'seconds');
|
||||
this.keyExpiry = DateTime.local().plus({ seconds: this.keyDurationSeconds });
|
||||
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', {
|
||||
|
||||
@@ -52,7 +52,7 @@ export type TokenIssuer = {
|
||||
*/
|
||||
export type StoredKey = {
|
||||
key: AnyJWK;
|
||||
createdAt: moment.Moment;
|
||||
createdAt: luxon.DateTime;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user