Skip to content

Commit

Permalink
feat(shared): allow old api keys BM-1057
Browse files Browse the repository at this point in the history
  • Loading branch information
blacha committed Jul 25, 2024
1 parent bb33075 commit c18be07
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
7 changes: 6 additions & 1 deletion packages/shared/src/__tests__/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { afterEach, beforeEach, describe, it } from 'node:test';

import { decodeTime, encodeTime, ulid } from 'ulid';

import { getApiKey, OneDayMs, truncateApiKey } from '../api.js';
import { getApiKey, isValidApiKey, OneDayMs, truncateApiKey } from '../api.js';

declare const global: {
localStorage?: { getItem: (a: string) => string | null; setItem: (k: string, v: string) => void };
Expand Down Expand Up @@ -38,6 +38,11 @@ describe('ApiKey', () => {
assert.equal(getApiKey(), newKey);
});

it('should allow api keys that are very old', () => {
const fakeUlid = 'c' + encodeTime(new Date('2020-01-01T00:00:00.000Z').getTime(), 10) + ulid().slice(10);
assert.deepEqual(isValidApiKey(fakeUlid), { valid: true, key: fakeUlid });
});

it('should generate new keys after they expire', (t) => {
const setSpy = t.mock.method(localStorage, 'setItem');
// Generate a key that is about 31 days old
Expand Down
7 changes: 4 additions & 3 deletions packages/shared/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const hasLocalStorage = (): boolean => typeof localStorage !== 'undefined';
export const OneDayMs = 24 * 60 * 60 * 1000;
/** Generate a new api key for the user every 30 days */
const ApiKeyExpireMs = 30 * OneDayMs;
const ApiKeyMaxAgeMs = 91 * OneDayMs;
export const ApiKeyMaxAgeMs = 91 * OneDayMs;

function newApiKey(): string {
const newKey = 'c' + ulid().toLowerCase();
Expand Down Expand Up @@ -46,10 +46,11 @@ export function isValidApiKey(apiKey?: string | null): ApiKeyStatus {
if (!apiKey.startsWith('c') && !apiKey.startsWith('d')) return { valid: false, message: 'malformed' };
const ulidId = apiKey.slice(1).toUpperCase();
try {
const ulidTime = decodeTime(ulidId);
decodeTime(ulidId); // validate the key looks valid
if (apiKey.startsWith('d')) return { valid: true, key: apiKey };

if (Date.now() - ulidTime > ApiKeyMaxAgeMs) return { valid: false, message: 'expired' };
// Re-enable to disable older api keys
// if (Date.now() - ulidTime > ApiKeyMaxAgeMs) return { valid: false, message: 'expired' };
} catch (e) {
return { valid: false, message: 'malformed' };
}
Expand Down

0 comments on commit c18be07

Please sign in to comment.