UNPKG

unleash-server

Version:

Unleash is an enterprise ready feature flag service. It provides different strategies for handling feature flags.

183 lines • 6.92 kB
import dbInit from '../helpers/database-init.js'; import getLogger from '../../fixtures/no-logger.js'; import { createTestConfig } from '../../config/test-config.js'; import { ApiTokenType } from '../../../lib/types/model.js'; import { DEFAULT_ENV } from '../../../lib/util/constants.js'; import { addDays, subDays } from 'date-fns'; import { createProjectService } from '../../../lib/features/index.js'; import { EdgeService } from '../../../lib/services/index.js'; import { SYSTEM_USER_AUDIT, SYSTEM_USER_ID, TEST_AUDIT_USER, } from '../../../lib/types/index.js'; import { createApiTokenService } from '../../../lib/features/api-tokens/createApiTokenService.js'; import { randomBytes } from 'node:crypto'; let db; let stores; let edgeService; let projectService; let user; beforeAll(async () => { const config = createTestConfig({ server: { baseUriPath: '/test' }, experimental: { flags: { useMemoizedActiveTokens: true, }, }, edgeMasterKey: '5ja3QXrqi4T2A+V+0QOw8eTA68lsHQE81vNO80MGrhw=', }); db = await dbInit('api_token_service_serial', getLogger); stores = db.stores; const project = { id: 'test-project', name: 'Test Project', description: 'Fancy', mode: 'open', defaultStickiness: 'clientId', }; user = await stores.userStore.insert({ name: 'Some Name', email: 'test@getunleash.io', }); projectService = createProjectService(db.rawDatabase, config); await projectService.createProject(project, user, TEST_AUDIT_USER); const apiTokenService = createApiTokenService(db.rawDatabase, config); edgeService = new EdgeService({ edgeTokenStore: db.stores.edgeTokenStore }, { apiTokenService }, config); }); afterAll(async () => { if (db) { await db.destroy(); } }); afterEach(async () => { await edgeService.deleteAllTokens(); const tokens = await stores.apiTokenStore.getAll(); const deleteAll = tokens.map((t) => stores.apiTokenStore.delete(t.secret)); await Promise.all(deleteAll); }); test('should only return valid tokens', async () => { const now = Date.now(); const yesterday = subDays(now, 1); const tomorrow = addDays(now, 1); const expiredToken = await stores.apiTokenStore.insert({ tokenName: 'expired', secret: '*:environment.expired-secret', type: ApiTokenType.BACKEND, expiresAt: yesterday, projects: ['*'], environment: DEFAULT_ENV, }, SYSTEM_USER_ID); const activeToken = await stores.apiTokenStore.insert({ tokenName: 'default-valid', secret: '*:environment.valid-secret', type: ApiTokenType.BACKEND, expiresAt: tomorrow, projects: ['*'], environment: DEFAULT_ENV, }, SYSTEM_USER_ID); const response = await edgeService.getValidTokens([ activeToken.secret, expiredToken.secret, ]); expect(response.tokens.length).toBe(1); expect(activeToken.secret).toBe(response.tokens[0].token); }); describe('Enterprise Edge - Generated tokens', () => { const clientId = 'enterprise-edge'; beforeAll(async () => { await edgeService.saveClient(clientId, 'mySecret'); const project1 = { id: 'project1', name: 'Test Project', description: 'Fancy', mode: 'open', defaultStickiness: 'clientId', }; await projectService.createProject(project1, user, SYSTEM_USER_AUDIT); const project2 = { id: 'project2', name: 'Another Project', description: 'Not so fancy', mode: 'open', defaultStickiness: 'clientId', }; await projectService.createProject(project2, user, SYSTEM_USER_AUDIT); const aProject = { id: 'a-project', name: 'A Project', description: 'Fancy', mode: 'open', defaultStickiness: 'clientId', }; await projectService.createProject(aProject, user, SYSTEM_USER_AUDIT); const zProject = { id: 'z-project', name: 'Z Project', description: 'Fancy', mode: 'open', defaultStickiness: 'clientId', }; await projectService.createProject(zProject, user, SYSTEM_USER_AUDIT); }); test('saving a token should make it fetchable from clientId, environment and projects', async () => { const tokens = await edgeService.getOrCreateTokens(clientId, { tokens: [ { environment: 'development', projects: ['project1', 'project2'], }, ], }); expect(tokens.tokens).toHaveLength(1); const refetched = await edgeService.getOrCreateTokens('enterprise-edge', { tokens: [ { environment: 'development', projects: ['project1', 'project2'], }, ], }); const first = tokens.tokens[0]; const second = refetched.tokens[0]; expect(first.token).toStrictEqual(second.token); }); test(`order of projects doesn't matter for uniqueness comparison`, async () => { const tokens = await edgeService.getOrCreateTokens(clientId, { tokens: [ { environment: 'development', projects: [ 'a-project', 'project2', 'project1', 'z-project', ], }, ], }); expect(tokens.tokens).toHaveLength(1); const refetched = await edgeService.getOrCreateTokens(clientId, { tokens: [ { environment: 'development', projects: [ 'z-project', 'project1', 'project2', 'a-project', ], }, ], }); const first = tokens.tokens[0]; const second = refetched.tokens[0]; expect(first.token).toStrictEqual(second.token); }); test(`Deletes nonces that have expired`, async () => { const nonce = randomBytes(16).toString('hex'); const expiry = subDays(new Date(), 1); await expect(stores.edgeTokenStore.registerNonce(clientId, nonce, expiry)).resolves.not.toThrow(); await expect(stores.edgeTokenStore.registerNonce(clientId, nonce, expiry)).rejects.toThrowError(); await edgeService.deleteExpiredNonces(); await expect(stores.edgeTokenStore.registerNonce(clientId, nonce, expiry)).resolves.not.toThrow(); }); }); //# sourceMappingURL=edge-service.e2e.test.js.map