diff --git a/.eslintrc.yml b/.eslintrc.yml index 026431e2..5d3449bb 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -27,5 +27,6 @@ rules: "@typescript-eslint/consistent-type-imports": off "@typescript-eslint/no-misused-promises": off "@typescript-eslint/no-non-null-assertion": off + "@typescript-eslint/no-floating-promises": off "react/react-in-jsx-scope": off diff --git a/apps/cli/dev_server.ts b/apps/cli/dev_server.ts index 67d7bcfb..3a4ec3cb 100644 --- a/apps/cli/dev_server.ts +++ b/apps/cli/dev_server.ts @@ -1,7 +1,7 @@ import path from 'path'; import startServer from './src/commands/start_server'; import exitWithMessage from './src/utils/exit_with_message'; -import { Mode } from './src/config'; +import { DEFAULT_CONFIG, Mode } from './src/config'; const data = process.env.CICADA_DATA; if (!data) { @@ -12,4 +12,9 @@ if (!data) { const absoluteData = path.isAbsolute(data!) ? data! : path.resolve(process.cwd(), data!); -startServer({ mode: Mode.DEVELOPMENT, port: 8000, data: absoluteData }); +startServer({ + mode: Mode.DEVELOPMENT, + port: 8000, + data: absoluteData, + jwtExpiry: DEFAULT_CONFIG.jwtExpiry, +}); diff --git a/apps/cli/src/commands/start_server/index.ts b/apps/cli/src/commands/start_server/index.ts index 15b0f04c..774379d5 100644 --- a/apps/cli/src/commands/start_server/index.ts +++ b/apps/cli/src/commands/start_server/index.ts @@ -14,14 +14,16 @@ import { getFormApp } from './form_app'; import { getPwaApp } from './pwa_app'; import { getBaseApp } from './base_app'; import i18n from './middlewares/i18n'; +import ms from 'ms'; function printConfig() { const config = getConfig(); - const printConfigKeys: (keyof Config)[] = ['mode', 'port', 'data']; + const printConfigKeys: Array = ['mode', 'port', 'data']; console.log('---'); for (const key of printConfigKeys) { console.log(`${key}: ${config[key]}`); } + console.log(`jwtExpiry: ${ms(config.jwtExpiry)}`); console.log('---'); } @@ -29,12 +31,14 @@ export default async ({ mode, port, data, + jwtExpiry, }: { mode: Mode; port: number; data: string; + jwtExpiry: number; }) => { - updateConfig({ mode, port, data }); + updateConfig({ mode, port, data, jwtExpiry }); printConfig(); await initialize(); diff --git a/apps/cli/src/config.ts b/apps/cli/src/config.ts index 851d7d49..83e7ae87 100644 --- a/apps/cli/src/config.ts +++ b/apps/cli/src/config.ts @@ -10,6 +10,8 @@ export interface Config { data: string; port: number; + + jwtExpiry: number; } export const DEFAULT_CONFIG: Config = { @@ -17,6 +19,7 @@ export const DEFAULT_CONFIG: Config = { data: `${process.cwd()}/cicada`, port: 8000, + jwtExpiry: 1000 * 60 * 60 * 24 * 180, }; let config: Config = JSON.parse(JSON.stringify(DEFAULT_CONFIG)); diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index b792f947..37f1631f 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -9,6 +9,7 @@ import upgradeData from './commands/upgrade_data'; import fixData from './commands/fix_data'; import { FIRST_USER_ID } from './constants'; import { DEFAULT_CONFIG, Mode } from './config'; +import ms from 'ms'; const program = new Command() .name('cicada') @@ -25,15 +26,21 @@ program .option('--mode [mode]', 'development or production') .option('--data [data]', 'data directory location') .option('--port [port]', 'port of http server') + .option( + '--jwt-expiry [jwtExpiry]', + 'expiry for jwt, use [ms](https://www.npmjs.com/package/ms) to parse string to millisecond', + ) .action( async ({ mode, data, port, + jwtExpiry, }: { mode?: Mode; data?: string; port?: string; + jwtExpiry?: string; }) => { if (mode && !Object.values(Mode).includes(mode)) { return exitWithMessage(`[ ${mode} ] is not a valid mode`); @@ -44,10 +51,11 @@ program ? data : path.resolve(process.cwd(), data) : DEFAULT_CONFIG.data; - return startServer({ - mode: mode || DEFAULT_CONFIG.mode, + return await startServer({ + mode: mode ?? DEFAULT_CONFIG.mode, data: absoluteData, port: port ? Number(port) : DEFAULT_CONFIG.port, + jwtExpiry: jwtExpiry ? ms(jwtExpiry) : DEFAULT_CONFIG.jwtExpiry, }); }, ); diff --git a/apps/cli/src/platform/jwt.ts b/apps/cli/src/platform/jwt.ts index 232d9c5e..6dc9eb51 100644 --- a/apps/cli/src/platform/jwt.ts +++ b/apps/cli/src/platform/jwt.ts @@ -1,9 +1,7 @@ import fs from 'fs'; import jwt from 'jsonwebtoken'; import generateRandomString from '#/utils/generate_random_string'; -import { getJWTSecretFilePath } from '@/config'; - -const JWT_TTL = 1000 * 60 * 60 * 24 * 180; +import { getConfig, getJWTSecretFilePath } from '@/config'; let secret: string = ''; const getSecret = () => { @@ -27,7 +25,7 @@ export function sign({ tokenIdentifier: string; }) { return jwt.sign({ userId, tokenIdentifier }, getSecret(), { - expiresIn: JWT_TTL / 1000, + expiresIn: getConfig().jwtExpiry / 1000, }); } @@ -35,7 +33,9 @@ export function verify(token: string): { userId: string; tokenIdentifier: string; } { - const payload = jwt.verify(token, getSecret()); - // @ts-expect-error + const payload = jwt.verify(token, getSecret()) as { + userId: string; + tokenIdentifier: string; + }; return payload; } diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 7bf5a71e..cfe99b10 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -12,5 +12,5 @@ "@/*": ["src/*"] } }, - "include": ["src/**/*", "../../global.d.ts"] + "include": ["dev_server.ts", "src/**/*", "../../global.d.ts"] } diff --git a/package-lock.json b/package-lock.json index f11ec298..6ff65fa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "koa-etag": "^4.0.0", "koa-send": "^5.0.1", "md5": "^2.3.0", + "ms": "^2.1.3", "multiparty": "^4.2.3", "nanospinner": "^1.1.0", "negotiator": "^0.6.3", @@ -8342,6 +8343,11 @@ } } }, + "node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/decamelize": { "version": "1.2.0", "dev": true, @@ -15220,8 +15226,9 @@ "license": "MIT" }, "node_modules/ms": { - "version": "2.1.2", - "license": "MIT" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -18273,11 +18280,6 @@ "node": ">= 0.8" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, "node_modules/send/node_modules/statuses": { "version": "2.0.1", "dev": true, diff --git a/package.json b/package.json index 78e81281..6fb90df6 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "koa-etag": "^4.0.0", "koa-send": "^5.0.1", "md5": "^2.3.0", + "ms": "^2.1.3", "multiparty": "^4.2.3", "nanospinner": "^1.1.0", "negotiator": "^0.6.3",