PronounsPage/server/jwt-cli.ts
Adaline Simonian 23a3862ca0
test: introduce snapshot-based smoke tests
- Adds a new test suite with Docker-based smoke tests for all locales.
  Can be run using the ./smoketest.sh script.
- Replaces all calls to Math.random() with a new helper that returns 0.5
  in snapshot testing mode, ensuring deterministic snapshots.
- Similarly replaces all calls to new Date() and Date.now() with new
  helpers that return a fixed date in snapshot testing mode.
- Replaces checks against NODE_ENV with APP_ENV, to ensure that the
  bundles can be built with Nuxt for testing without losing code that
  would otherwise be stripped out by production optimizations.
- Adds a database init script that can be used to initialize the
  database with a single admin user and a long-lived JWT token for use
  in automation tests.
- Adds a JWT decoding/encoding CLI tool for debugging JWTs.

Note: Snapshots are not checked in, and must be generated manually. See
test/__snapshots__/.gitignore for more information.
2025-02-02 23:11:19 -08:00

60 lines
1.6 KiB
TypeScript

import path from 'path';
import dotenv from './dotenv.ts';
import jwt from './jwt.ts';
// Command-line script for encrypting and decrypting JWTs. Useful for
// debugging and testing.
// Example usage:
// echo '{"key": "value"}' | APP_ENV=development PORT=3001 pnpm run-file server/jwt-cli.ts encrypt
// echo 'eyJ...' | APP_ENV=development pnpm run-file server/jwt-cli.ts decrypt
/**
* Sets up environment variables.
*/
function setupEnv(): void {
dotenv();
// Replace port 3000 in BASE_URL and ALL_LOCALES_URLS with port from PORT
if (process.env.PORT) {
process.env.BASE_URL =
process.env.BASE_URL?.replace(/:3000\b/g, `:${process.env.PORT}`);
process.env.ALL_LOCALES_URLS =
process.env.ALL_LOCALES_URLS?.replaceAll(/:3000\b/g, `:${process.env.PORT}`);
}
}
/**
* Main function.
*/
(async () => {
setupEnv();
if (process.argv.length < 3) {
console.error(`Usage: ${path.relative(process.cwd(), process.argv[1])} {encrypt|decrypt}`);
process.exit(2);
}
const operation = process.argv[2];
const input = await new Promise<string>((resolve) => {
let data = '';
process.stdin.on('data', (chunk) => data += chunk);
process.stdin.on('end', () => resolve(data));
});
switch (operation) {
case 'encrypt':
console.log(await jwt.sign(JSON.parse(input)));
break;
case 'decrypt':
console.log(JSON.stringify(await jwt.validate(input), null, 2));
break;
default:
console.error('Invalid operation! Use \'encrypt\' or \'decrypt\'.');
process.exit(1);
}
})();