mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
* Typecheck across packages that are built with esbuild * Boilerplate new Errors package * No need, tsup checks with --dts * Switch to tsup * Setup dev script * Add readme * More boilerplaty things * Finish createError function * Install @directus/random * Downgrade node types * Add utility function to check if an error is a DirectusError * Use new is-error check * Install errors package * Add failed validation common error * Export common errors * Move joi convertion to utils * Export failed validation * Use new failed validation error in validate-batch * Enhance typing output of createError * Remove outdir (handled by tsup now) * Replace Exception with Error * Replace exception in test * Remove exceptions from app * Remove exceptions from app * Remove failed validation exception from users service * Remove old failed validation exception from shared * Remove exceptions package in favor of errors * Uninstall exceptions * Replace baseexception check * Migrate content too large error * Critical detail * Replace ForbiddenException * WIP remove exceptions * Add ForbiddenError to errors * HitRateLimitError * Move validation related error/helper to new validation package * Add index * Add docs * Install random * Convert TokenExpired * Convert user-suspended * Convert invalid-credentials * Move UnsupportedMediaType * Replace wrong imports for forbidden * Convert invalid-ip * Move invalid provider * Move InvalidOtp * Convert InvalidToken * Move MethodNotAllowed * Convert range not satisfiable * Move unexpect response * Move UnprocessableContent * Move IllegalAssetTransformation * Move RouteNotFound * Finalize not found * Various db errors * Move value too long * Move not null * Move record-not-unique * Move value out of range * Finish db errors * Service unavailable * GQL errors * Update packages/validation/src/errors/failed-validation.ts Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> * Update packages/validation/src/errors/failed-validation.ts Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> * InvalidQuery * Add test for invalid query message constructor * Invalid Payload * Finalize exceptions move * Improve type of isDirectusError * Various fixes * Fix build in api * Update websocket exceptions use * Allow optional reason for invalid config * Update errors usage in utils * Remove unused package from errors * Update lockfile * Update api/src/auth/drivers/ldap.ts Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> * Update packages/validation/src/utils/joi-to-error-extensions.ts Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> * Put error codes in shared enum * Replace instanceof checks in api * Fix tests I think * Tweak override names * Fix linter warnings * Set snapshots * Start fixing BB tests * Fix blackbox tests * Add changeset * Update changeset * Update extension docs to use new createError abstraction * 🙄 * Fix graphql validation error name * 🥳 * use ErrorCode.Forbidden * fix blackbox auth login test * Add license files * Rename preMutationException to preMutationError * Remove unused ms dep & sort package.json * Remove periods from error messages for consistency Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> * Add optional code check * Use updated error code checker * Rename InvalidConfigError to InvalidProviderConfigError --------- Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com> Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch> Co-authored-by: ian <licitdev@gmail.com>
74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import jwt from 'jsonwebtoken';
|
|
import { expect, test, vi } from 'vitest';
|
|
import type { DirectusTokenPayload } from '../../src/types/index.js';
|
|
import { verifyAccessJWT, verifyJWT } from '../../src/utils/jwt.js';
|
|
import { TokenExpiredError, InvalidTokenError } from '../errors/index.js';
|
|
import { ServiceUnavailableError } from '../errors/index.js';
|
|
|
|
const payload: DirectusTokenPayload = { role: null, app_access: false, admin_access: false };
|
|
const secret = 'test-secret';
|
|
const options = { issuer: 'directus' };
|
|
|
|
test('Returns the payload of a correctly signed token', () => {
|
|
const token = jwt.sign(payload, secret, options);
|
|
const result = verifyJWT(token, secret);
|
|
|
|
expect(result['admin_access']).toEqual(payload.admin_access);
|
|
expect(result['app_access']).toEqual(payload.app_access);
|
|
expect(result['role']).toEqual(payload.role);
|
|
expect(result['iss']).toBe('directus');
|
|
expect(result['iat']).toBeTypeOf('number');
|
|
});
|
|
|
|
test('Throws TokenExpiredError when token used has expired', () => {
|
|
const token = jwt.sign({ ...payload, exp: new Date().getTime() / 1000 - 500 }, secret, options);
|
|
expect(() => verifyJWT(token, secret)).toThrow(TokenExpiredError);
|
|
});
|
|
|
|
const InvalidTokenCases = {
|
|
'wrong issuer': jwt.sign(payload, secret, { issuer: 'wrong' }),
|
|
'wrong secret': jwt.sign(payload, 'wrong-secret', options),
|
|
'string payload': jwt.sign('illegal payload', secret),
|
|
};
|
|
|
|
Object.entries(InvalidTokenCases).forEach(([title, token]) =>
|
|
test(`Throws InvalidTokenError - ${title}`, () => {
|
|
expect(() => verifyJWT(token, secret)).toThrow(InvalidTokenError);
|
|
})
|
|
);
|
|
|
|
test(`Throws ServiceUnavailableError for unexpected error from jsonwebtoken`, () => {
|
|
const mock = vi.spyOn(jwt, 'verify').mockImplementation(() => {
|
|
throw new Error();
|
|
});
|
|
|
|
const token = jwt.sign(payload, secret, options);
|
|
expect(() => verifyJWT(token, secret)).toThrow(ServiceUnavailableError);
|
|
mock.mockRestore();
|
|
});
|
|
|
|
const RequiredEntries: Array<keyof DirectusTokenPayload> = ['role', 'app_access', 'admin_access'];
|
|
|
|
RequiredEntries.forEach((entry) => {
|
|
test(`Throws InvalidTokenError if ${entry} not defined`, () => {
|
|
const { [entry]: _entryName, ...rest } = payload;
|
|
const token = jwt.sign(rest, secret, options);
|
|
expect(() => verifyAccessJWT(token, secret)).toThrow(InvalidTokenError);
|
|
});
|
|
});
|
|
|
|
test('Returns the payload of an access token', () => {
|
|
const payload = { id: 1, role: 1, app_access: true, admin_access: true };
|
|
const token = jwt.sign(payload, secret, options);
|
|
const result = verifyAccessJWT(token, secret);
|
|
|
|
expect(result).toEqual({
|
|
id: 1,
|
|
role: 1,
|
|
app_access: true,
|
|
admin_access: true,
|
|
share: undefined,
|
|
share_scope: undefined,
|
|
});
|
|
});
|