node-server-engine 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.commitlintrc.js +10 -10
- package/.nycrc +1 -3
- package/.releaserc.js +2 -1
- package/README.md +194 -138
- package/dist/const/metrics.js.map +1 -1
- package/dist/db/models/index.js.map +1 -1
- package/dist/entities/AWSS3/AWSS3.js +12 -12
- package/dist/entities/AWSS3/AWSS3.js.map +1 -1
- package/dist/entities/ElasticSearch/ElasticSearch.js.map +1 -1
- package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
- package/dist/entities/GoogleCloudStorage/GoogleCloudStorage.js +11 -11
- package/dist/entities/GoogleCloudStorage/GoogleCloudStorage.js.map +1 -1
- package/dist/entities/KeySet/KeySet.js.map +1 -1
- package/dist/entities/PubSub/PubSub.js.map +1 -1
- package/dist/entities/PushNotification/PushNotification.js.map +1 -1
- package/dist/entities/Redis/Redis.js +3 -3
- package/dist/entities/Redis/Redis.js.map +1 -1
- package/dist/entities/SecretManager/SecretManager.js +3 -3
- package/dist/entities/SecretManager/SecretManager.js.map +1 -1
- package/dist/entities/Sequelize/Sequelize.config.js.map +1 -1
- package/dist/entities/Sequelize/Sequelize.js.map +1 -1
- package/dist/entities/Server/Server.js.map +1 -1
- package/dist/entities/Server/Server.types.js.map +1 -1
- package/dist/entities/index.js.map +1 -1
- package/dist/middleware/checkPermission/checkPermission.js.map +1 -1
- package/dist/middleware/checkPermission/index.js.map +1 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/multiPartFileUploader/multiPartFileUploader.js.map +1 -1
- package/dist/middleware/requestMetrics/requestMetrics.js.map +1 -1
- package/dist/middleware/swaggerDocs/swaggerDocs.js.map +1 -1
- package/dist/middleware/verificationToken/verificationToken.js.map +1 -1
- package/dist/utils/createSortedObject/createSortedObject.js.map +1 -1
- package/dist/utils/dbMigration/dbMigration.d.ts +1 -0
- package/dist/utils/dbMigration/dbMigration.js +13 -2
- package/dist/utils/dbMigration/dbMigration.js.map +1 -1
- package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.js +29 -3
- package/dist/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.js.map +1 -1
- package/dist/utils/jwt/jwt.js.map +1 -1
- package/dist/utils/jwt/jwt.types.js.map +1 -1
- package/dist/utils/report/output.js.map +1 -1
- package/dist/utils/report/report.js.map +1 -1
- package/dist/utils/semverCompare/semverCompare.js.map +1 -1
- package/dist/utils/verificationToken/verificationToken.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dbMigration.js","names":["_fs","require","_path","_umzug","_migrateMetadataTable","_models","_EngineError","_Sequelize","_report","_semverCompare","cache","_interopRequireWildcard","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","namespace","getMigrationPaths","prodDefaultPath","join","process","cwd","devDefaultPath","path","env","DB_MIGRATIONS_DIR","NODE_ENV","filter","existsSync","lstatSync","isDirectory","reportDebug","message","data","prodPath","devPath","customPath","map","p","runPendingMigrations","sequelize","EngineError","sqlHost","SQL_HOST","sqlDb","SQL_DB","sqlUser","SQL_USER","nodeEnv","migrateMetadataTable","migrationPaths","length","migrator","Umzug","migrations","glob","resolve","name","context","nameWithoutExtension","replace","migrationPromise","specifier","Promise","then","s","up","migration","down","getQueryInterface","storage","SequelizeStorage","logger","console","reportInfo","error","Error","String","stack","undefined","rollbackMigrations","BUILD_ID","SequelizeMeta","findAll","order","raw","rollbackUntil","find","version","semverCompare","buildId","to","testRecreateDB","options","query","SQL_TYPE","clean","testClearDB","transaction","clearDbTransaction","model","keys","models","includeMetadata","table","tableName"],"sources":["../../../src/utils/dbMigration/dbMigration.ts"],"sourcesContent":["import { existsSync, lstatSync } from 'fs';\nimport { join } from 'path';\nimport { Sequelize, Transaction } from 'sequelize';\nimport { Umzug, SequelizeStorage } from 'umzug';\nimport { ClearDbOptions, RecreateDbOptions } from './dbMigration.types';\nimport { migrateMetadataTable } from './migrateMetadataTable';\nimport { SequelizeMeta } from 'db/models';\nimport { EngineError } from 'entities/EngineError';\nimport { sequelize } from 'entities/Sequelize';\nimport { reportDebug, reportInfo } from 'utils/report';\nimport { semverCompare } from 'utils/semverCompare';\n\nconst namespace = 'engine:utils:dbMigration';\n\nfunction getMigrationPaths(): Array<string> | undefined {\n // We look between possibilities for the first directory that exists and matches our expectations\n // First a user specified one, then the production default, then the development default\n const prodDefaultPath = join(process.cwd(), './dist/db/migrations');\n const devDefaultPath = join(process.cwd(), './src/db/migrations');\n const path = [\n process.env.DB_MIGRATIONS_DIR,\n process.env.NODE_ENV === 'prod' ? prodDefaultPath : devDefaultPath\n ].filter((path) => path && existsSync(path) && lstatSync(path).isDirectory());\n reportDebug({\n namespace,\n message: 'Obtaining Umzug migration options',\n data: {\n path,\n prodPath: prodDefaultPath,\n devPath: devDefaultPath,\n customPath: process.env.DB_MIGRATIONS_DIR\n }\n });\n return path.map((p) =>\n process.env.NODE_ENV === 'prod' ? `${p}/*.js` : `${p}/*.ts`\n );\n}\n\n/** Run all the non-executed migrations one by one */\nexport async function runPendingMigrations(): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n \n try {\n reportDebug({\n namespace,\n message: 'Starting migration process',\n data: {\n sqlHost: process.env.SQL_HOST,\n sqlDb: process.env.SQL_DB,\n sqlUser: process.env.SQL_USER,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n // First make sure that the metadata table is up to date\n reportDebug({\n namespace,\n message: 'Migrating metadata table'\n });\n await migrateMetadataTable(sequelize);\n \n const migrationPaths = getMigrationPaths();\n\n if (!migrationPaths || migrationPaths.length <= 0) {\n reportDebug({\n namespace,\n message: 'No valid migration paths found.',\n data: { migrationPaths }\n });\n return;\n }\n\n // Process migrations sequentially to avoid race conditions\n for (const path of migrationPaths) {\n reportDebug({\n namespace,\n message: 'Processing migration path',\n data: { path }\n });\n\n const migrator = new Umzug({\n migrations: {\n glob: path,\n resolve: ({ name, path, context }) => {\n const nameWithoutExtension = name.replace(/\\.(ts|js)$/, '');\n \n // Use dynamic import for better TypeScript/ES module support\n const migrationPromise = import(path || '');\n return {\n name: nameWithoutExtension,\n up: async () => {\n reportDebug({\n namespace,\n message: `Running migration: ${nameWithoutExtension}`\n });\n const migration = await migrationPromise;\n return migration.up(context);\n },\n down: async () => {\n const migration = await migrationPromise;\n return migration.down(context);\n }\n };\n }\n },\n context: sequelize.getQueryInterface(),\n storage: new SequelizeStorage({ sequelize }),\n logger: console\n });\n\n reportDebug({\n namespace,\n message: 'Starting pending database migrations',\n data: { path }\n });\n \n await migrator.up();\n \n reportInfo({\n message: 'Database migration completed successfully',\n data: { path }\n });\n }\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Migration failed with error',\n data: {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n sqlHost: process.env.SQL_HOST,\n sqlDb: process.env.SQL_DB\n }\n });\n throw error;\n }\n}\n\n/** Rollback all migrations up to a specified target version */\nexport async function rollbackMigrations(): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n if (!process.env.BUILD_ID)\n throw new EngineError({ message: 'BUILD_ID is not defined' });\n\n // Fetch executed migrations in ascending order\n const migrations = await SequelizeMeta.findAll({\n order: [['name', 'ASC']],\n raw: true\n });\n const rollbackUntil = migrations.find(\n (migration) =>\n migration.version &&\n semverCompare(migration.version, process.env.BUILD_ID as string) === 1\n );\n\n if (!rollbackUntil) {\n reportDebug({\n namespace,\n message: 'No rollback target found for the current BUILD_ID.',\n data: { buildId: process.env.BUILD_ID }\n });\n return;\n }\n\n const migrationPaths = getMigrationPaths();\n\n if (!migrationPaths || migrationPaths.length <= 0) {\n reportDebug({\n namespace,\n message: 'No valid migration paths found for rollback.',\n data: { migrationPaths }\n });\n return;\n }\n\n // Process rollback migrations sequentially\n for (const path of migrationPaths) {\n const migrator = new Umzug({\n migrations: {\n glob: path,\n resolve: ({ name, path, context }) => {\n // Strip file extension to ensure consistent naming across .ts and .js files\n const nameWithoutExtension = name.replace(/\\.(ts|js)$/, '');\n \n const migrationPromise = import(path || '');\n return {\n name: nameWithoutExtension,\n up: async () => {\n const migration = await migrationPromise;\n return migration.up(context);\n },\n down: async () => {\n const migration = await migrationPromise;\n return migration.down(context);\n }\n };\n }\n },\n context: sequelize.getQueryInterface(),\n storage: new SequelizeStorage({ sequelize }),\n logger: console\n });\n\n reportDebug({\n namespace,\n message: `Rolling back migrations up to: ${rollbackUntil.name}`,\n data: { path }\n });\n\n await migrator.down({ to: rollbackUntil.name });\n }\n}\n\n/**\n * Recreate the whole database\n * Quick way to make sure that we are working on a clean database\n * /!\\ Should only be used when running tests\n */\nexport async function testRecreateDB(\n options: RecreateDbOptions = {}\n): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n await sequelize.query(\n `DROP SCHEMA public${process.env.SQL_TYPE === 'postgres' ? ' CASCADE' : ''}`\n );\n await sequelize.query(`CREATE SCHEMA public`);\n if (!options.clean) await runPendingMigrations();\n}\n\n/**\n * Empty all the schemas in the database\n * Quick way to flush the database data while keep the structure\n * /!\\ Should only be used when running tests\n */\nexport async function testClearDB(options: ClearDbOptions = {}): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n await sequelize.transaction(clearDbTransaction(sequelize, options));\n}\n\n/** DB clearing transaction */\nfunction clearDbTransaction(sequelize: Sequelize, options: ClearDbOptions) {\n return async (t: Transaction): Promise<void> => {\n for (const model of Object.keys(sequelize.models)) {\n // We ignore the migration metadata schema\n if (!options.includeMetadata && model === 'sequelizeMeta') continue;\n const table = sequelize.models[model].tableName;\n await sequelize.query(\n `TRUNCATE ${table}${process.env.SQL_TYPE === 'postgres' ? ' CASCADE' : ''};`,\n {\n raw: true,\n transaction: t\n }\n );\n }\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"dbMigration.js","names":["_fs","require","_path","_umzug","_migrateMetadataTable","_models","_EngineError","_Sequelize","_report","_semverCompare","cache","_interopRequireWildcard","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","namespace","getMigrationPaths","prodDefaultPath","join","process","cwd","devDefaultPath","isProduction","includes","env","NODE_ENV","path","DB_MIGRATIONS_DIR","filter","existsSync","lstatSync","isDirectory","reportDebug","message","data","prodPath","devPath","customPath","map","p","getMigrationExtension","directory","hasTypeScript","readdirSync","some","file","endsWith","runPendingMigrations","sequelize","EngineError","sqlHost","SQL_HOST","sqlDb","SQL_DB","sqlUser","SQL_USER","nodeEnv","migrateMetadataTable","migrationPaths","length","migrator","Umzug","migrations","glob","resolve","name","context","nameWithoutExtension","replace","migrationPromise","specifier","Promise","then","s","up","migration","down","getQueryInterface","storage","SequelizeStorage","logger","console","reportInfo","error","Error","String","stack","undefined","rollbackMigrations","BUILD_ID","SequelizeMeta","findAll","order","raw","rollbackUntil","find","version","semverCompare","buildId","to","testRecreateDB","options","query","SQL_TYPE","clean","testClearDB","transaction","clearDbTransaction","model","keys","models","includeMetadata","table","tableName"],"sources":["../../../src/utils/dbMigration/dbMigration.ts"],"sourcesContent":["import { existsSync, lstatSync, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { Sequelize, Transaction } from 'sequelize';\nimport { Umzug, SequelizeStorage } from 'umzug';\nimport { ClearDbOptions, RecreateDbOptions } from './dbMigration.types';\nimport { migrateMetadataTable } from './migrateMetadataTable';\nimport { SequelizeMeta } from 'db/models';\nimport { EngineError } from 'entities/EngineError';\nimport { sequelize } from 'entities/Sequelize';\nimport { reportDebug, reportInfo } from 'utils/report';\nimport { semverCompare } from 'utils/semverCompare';\n\nconst namespace = 'engine:utils:dbMigration';\n\nexport function getMigrationPaths(): Array<string> | undefined {\n // We look between possibilities for the first directory that exists and matches our expectations\n // First a user specified one, then the production default, then the development default\n const prodDefaultPath = join(process.cwd(), './dist/db/migrations');\n const devDefaultPath = join(process.cwd(), './src/db/migrations');\n const isProduction = ['prod', 'production'].includes(\n process.env.NODE_ENV ?? ''\n );\n const path = [\n process.env.DB_MIGRATIONS_DIR,\n isProduction ? prodDefaultPath : devDefaultPath\n ].filter(\n (path): path is string =>\n !!path && existsSync(path) && lstatSync(path).isDirectory()\n );\n reportDebug({\n namespace,\n message: 'Obtaining Umzug migration options',\n data: {\n path,\n prodPath: prodDefaultPath,\n devPath: devDefaultPath,\n customPath: process.env.DB_MIGRATIONS_DIR\n }\n });\n return path.map((p) => `${p}/*.${getMigrationExtension(p)}`);\n}\n\n/**\n * Detect whether a migration folder holds TypeScript sources or compiled JavaScript,\n * so migrations are found regardless of the NODE_ENV value\n */\nfunction getMigrationExtension(directory: string): 'ts' | 'js' {\n const hasTypeScript = readdirSync(directory).some(\n (file) => file.endsWith('.ts') && !file.endsWith('.d.ts')\n );\n return hasTypeScript ? 'ts' : 'js';\n}\n\n/** Run all the non-executed migrations one by one */\nexport async function runPendingMigrations(): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n\n try {\n reportDebug({\n namespace,\n message: 'Starting migration process',\n data: {\n sqlHost: process.env.SQL_HOST,\n sqlDb: process.env.SQL_DB,\n sqlUser: process.env.SQL_USER,\n nodeEnv: process.env.NODE_ENV\n }\n });\n\n // First make sure that the metadata table is up to date\n reportDebug({\n namespace,\n message: 'Migrating metadata table'\n });\n await migrateMetadataTable(sequelize);\n\n const migrationPaths = getMigrationPaths();\n\n if (!migrationPaths || migrationPaths.length <= 0) {\n reportDebug({\n namespace,\n message: 'No valid migration paths found.',\n data: { migrationPaths }\n });\n return;\n }\n\n // Process migrations sequentially to avoid race conditions\n for (const path of migrationPaths) {\n reportDebug({\n namespace,\n message: 'Processing migration path',\n data: { path }\n });\n\n const migrator = new Umzug({\n migrations: {\n glob: path,\n resolve: ({ name, path, context }) => {\n const nameWithoutExtension = name.replace(/\\.(ts|js)$/, '');\n\n // Use dynamic import for better TypeScript/ES module support\n const migrationPromise = import(path || '');\n return {\n name: nameWithoutExtension,\n up: async () => {\n reportDebug({\n namespace,\n message: `Running migration: ${nameWithoutExtension}`\n });\n const migration = await migrationPromise;\n return migration.up(context);\n },\n down: async () => {\n const migration = await migrationPromise;\n return migration.down(context);\n }\n };\n }\n },\n context: sequelize.getQueryInterface(),\n storage: new SequelizeStorage({ sequelize }),\n logger: console\n });\n\n reportDebug({\n namespace,\n message: 'Starting pending database migrations',\n data: { path }\n });\n\n await migrator.up();\n\n reportInfo({\n message: 'Database migration completed successfully',\n data: { path }\n });\n }\n } catch (error) {\n reportDebug({\n namespace,\n message: 'Migration failed with error',\n data: {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n sqlHost: process.env.SQL_HOST,\n sqlDb: process.env.SQL_DB\n }\n });\n throw error;\n }\n}\n\n/** Rollback all migrations up to a specified target version */\nexport async function rollbackMigrations(): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n if (!process.env.BUILD_ID)\n throw new EngineError({ message: 'BUILD_ID is not defined' });\n\n // Fetch executed migrations in ascending order\n const migrations = await SequelizeMeta.findAll({\n order: [['name', 'ASC']],\n raw: true\n });\n const rollbackUntil = migrations.find(\n (migration) =>\n migration.version &&\n semverCompare(migration.version, process.env.BUILD_ID as string) === 1\n );\n\n if (!rollbackUntil) {\n reportDebug({\n namespace,\n message: 'No rollback target found for the current BUILD_ID.',\n data: { buildId: process.env.BUILD_ID }\n });\n return;\n }\n\n const migrationPaths = getMigrationPaths();\n\n if (!migrationPaths || migrationPaths.length <= 0) {\n reportDebug({\n namespace,\n message: 'No valid migration paths found for rollback.',\n data: { migrationPaths }\n });\n return;\n }\n\n // Process rollback migrations sequentially\n for (const path of migrationPaths) {\n const migrator = new Umzug({\n migrations: {\n glob: path,\n resolve: ({ name, path, context }) => {\n // Strip file extension to ensure consistent naming across .ts and .js files\n const nameWithoutExtension = name.replace(/\\.(ts|js)$/, '');\n\n const migrationPromise = import(path || '');\n return {\n name: nameWithoutExtension,\n up: async () => {\n const migration = await migrationPromise;\n return migration.up(context);\n },\n down: async () => {\n const migration = await migrationPromise;\n return migration.down(context);\n }\n };\n }\n },\n context: sequelize.getQueryInterface(),\n storage: new SequelizeStorage({ sequelize }),\n logger: console\n });\n\n reportDebug({\n namespace,\n message: `Rolling back migrations up to: ${rollbackUntil.name}`,\n data: { path }\n });\n\n await migrator.down({ to: rollbackUntil.name });\n }\n}\n\n/**\n * Recreate the whole database\n * Quick way to make sure that we are working on a clean database\n * /!\\ Should only be used when running tests\n */\nexport async function testRecreateDB(\n options: RecreateDbOptions = {}\n): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n await sequelize.query(\n `DROP SCHEMA public${process.env.SQL_TYPE === 'postgres' ? ' CASCADE' : ''}`\n );\n await sequelize.query(`CREATE SCHEMA public`);\n if (!options.clean) await runPendingMigrations();\n}\n\n/**\n * Empty all the schemas in the database\n * Quick way to flush the database data while keep the structure\n * /!\\ Should only be used when running tests\n */\nexport async function testClearDB(options: ClearDbOptions = {}): Promise<void> {\n if (!sequelize)\n throw new EngineError({ message: 'Sequelize is not initialized' });\n await sequelize.transaction(clearDbTransaction(sequelize, options));\n}\n\n/** DB clearing transaction */\nfunction clearDbTransaction(sequelize: Sequelize, options: ClearDbOptions) {\n return async (t: Transaction): Promise<void> => {\n for (const model of Object.keys(sequelize.models)) {\n // We ignore the migration metadata schema\n if (!options.includeMetadata && model === 'sequelizeMeta') continue;\n const table = sequelize.models[model].tableName;\n await sequelize.query(\n `TRUNCATE ${table}${process.env.SQL_TYPE === 'postgres' ? ' CASCADE' : ''};`,\n {\n raw: true,\n transaction: t\n }\n );\n }\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -8,6 +8,28 @@ var _sequelize = require("sequelize");
|
|
|
8
8
|
var _report = require("../../report");
|
|
9
9
|
const namespace = 'engine:utils:dbMigration';
|
|
10
10
|
|
|
11
|
+
/** List the tables of the current database (not of every database on the server) */
|
|
12
|
+
function listTablesQuery(sqlType) {
|
|
13
|
+
switch (sqlType) {
|
|
14
|
+
case 'sqlite':
|
|
15
|
+
return `SELECT name AS table_name FROM sqlite_master WHERE type = 'table'`;
|
|
16
|
+
case 'mysql':
|
|
17
|
+
return `SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE()`;
|
|
18
|
+
case 'postgres':
|
|
19
|
+
return `SELECT table_name FROM information_schema.tables WHERE table_schema = current_schema()`;
|
|
20
|
+
default:
|
|
21
|
+
return `SELECT table_name FROM information_schema.tables`;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Extract the table name from a result row, whatever shape the driver returns */
|
|
26
|
+
function getTableName(row) {
|
|
27
|
+
if (typeof row === 'string') return row;
|
|
28
|
+
if (Array.isArray(row)) return getTableName(row[0]);
|
|
29
|
+
if (row && typeof row === 'object') return getTableName(Object.values(row)[0]);
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
11
33
|
/**
|
|
12
34
|
* Run migrations on the metadata table
|
|
13
35
|
* The table containing the migrations metadata cannot be handled through migrations
|
|
@@ -19,7 +41,7 @@ async function migrateMetadataTable(sequelize) {
|
|
|
19
41
|
namespace,
|
|
20
42
|
message: 'Executing metadata migration routine'
|
|
21
43
|
});
|
|
22
|
-
const query =
|
|
44
|
+
const query = listTablesQuery(process.env.SQL_TYPE);
|
|
23
45
|
(0, _report.reportDebug)({
|
|
24
46
|
namespace,
|
|
25
47
|
message: 'Checking for existing metadata tables',
|
|
@@ -32,8 +54,9 @@ async function migrateMetadataTable(sequelize) {
|
|
|
32
54
|
const tables = await sequelize.query(query, {
|
|
33
55
|
type: _sequelize.QueryTypes.SELECT
|
|
34
56
|
});
|
|
35
|
-
const
|
|
36
|
-
const
|
|
57
|
+
const tableNames = tables.map(getTableName);
|
|
58
|
+
const hasCustomSequelizeMeta = tableNames.includes('sequelize_meta');
|
|
59
|
+
const hasLegacySequelizeMeta = tableNames.includes('SequelizeMeta');
|
|
37
60
|
if (!hasCustomSequelizeMeta) {
|
|
38
61
|
(0, _report.reportDebug)({
|
|
39
62
|
namespace,
|
|
@@ -45,6 +68,7 @@ async function migrateMetadataTable(sequelize) {
|
|
|
45
68
|
switch (process.env.SQL_TYPE) {
|
|
46
69
|
case 'mysql':
|
|
47
70
|
case 'postgres':
|
|
71
|
+
case 'sqlite':
|
|
48
72
|
createTableQuery = `
|
|
49
73
|
CREATE TABLE sequelize_meta (
|
|
50
74
|
name VARCHAR(100) PRIMARY KEY,
|
|
@@ -98,6 +122,8 @@ async function migrateMetadataTable(sequelize) {
|
|
|
98
122
|
case 'mysql':
|
|
99
123
|
case 'postgres':
|
|
100
124
|
return `('${migration.name}', NULL, NOW(), NOW())`;
|
|
125
|
+
case 'sqlite':
|
|
126
|
+
return `('${migration.name}', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`;
|
|
101
127
|
case 'mssql':
|
|
102
128
|
return `('${migration.name}', NULL, GETDATE(), GETDATE())`;
|
|
103
129
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrateMetadataTable.js","names":["_sequelize","require","_report","namespace","
|
|
1
|
+
{"version":3,"file":"migrateMetadataTable.js","names":["_sequelize","require","_report","namespace","listTablesQuery","sqlType","getTableName","row","Array","isArray","Object","values","undefined","migrateMetadataTable","sequelize","reportDebug","message","query","process","env","SQL_TYPE","data","tables","type","QueryTypes","SELECT","tableNames","map","hasCustomSequelizeMeta","includes","hasLegacySequelizeMeta","createTableQuery","Error","RAW","migrations","insertQuery","migration","name","join","INSERT","error","reportError","String","stack","sqlHost","SQL_HOST"],"sources":["../../../../src/utils/dbMigration/migrateMetadataTable/migrateMetadataTable.ts"],"sourcesContent":["import { Sequelize, QueryTypes } from 'sequelize';\nimport { SequelizeMeta } from 'db/models';\nimport { reportDebug, reportError } from 'utils/report';\n\nconst namespace = 'engine:utils:dbMigration';\n\n/** List the tables of the current database (not of every database on the server) */\nfunction listTablesQuery(sqlType?: string): string {\n switch (sqlType) {\n case 'sqlite':\n return `SELECT name AS table_name FROM sqlite_master WHERE type = 'table'`;\n case 'mysql':\n return `SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE()`;\n case 'postgres':\n return `SELECT table_name FROM information_schema.tables WHERE table_schema = current_schema()`;\n default:\n return `SELECT table_name FROM information_schema.tables`;\n }\n}\n\n/** Extract the table name from a result row, whatever shape the driver returns */\nfunction getTableName(row: unknown): string | undefined {\n if (typeof row === 'string') return row;\n if (Array.isArray(row)) return getTableName(row[0]);\n if (row && typeof row === 'object')\n return getTableName(Object.values(row)[0]);\n return undefined;\n}\n\n/**\n * Run migrations on the metadata table\n * The table containing the migrations metadata cannot be handled through migrations\n * Therefore, we use a more classic approach with this function and pure SQL queries\n */\nexport async function migrateMetadataTable(\n sequelize: Sequelize\n): Promise<void> {\n try {\n reportDebug({ namespace, message: 'Executing metadata migration routine' });\n\n const query = listTablesQuery(process.env.SQL_TYPE);\n\n reportDebug({\n namespace,\n message: 'Checking for existing metadata tables',\n data: { sqlType: process.env.SQL_TYPE }\n });\n\n // We check if we have a custom sequelize_meta table yet\n const tables = await sequelize.query<Record<string, unknown>>(query, {\n type: QueryTypes.SELECT\n });\n const tableNames = tables.map(getTableName);\n\n const hasCustomSequelizeMeta = tableNames.includes('sequelize_meta');\n const hasLegacySequelizeMeta = tableNames.includes('SequelizeMeta');\n if (!hasCustomSequelizeMeta) {\n reportDebug({\n namespace,\n message: 'No metadata table found, creating new one'\n });\n\n // Define SQL for creating the table based on the database type\n let createTableQuery = '';\n\n switch (process.env.SQL_TYPE) {\n case 'mysql':\n case 'postgres':\n case 'sqlite':\n createTableQuery = `\n CREATE TABLE sequelize_meta (\n name VARCHAR(100) PRIMARY KEY,\n version VARCHAR(25),\n createdAt TIMESTAMP NOT NULL,\n updatedAt TIMESTAMP NOT NULL\n )`;\n break;\n case 'mssql':\n createTableQuery = `\n CREATE TABLE sequelize_meta (\n name VARCHAR(100) PRIMARY KEY,\n version VARCHAR(25),\n createdAt DATETIME NOT NULL,\n updatedAt DATETIME NOT NULL\n )`;\n break;\n default:\n throw new Error('Unsupported SQL type');\n }\n\n // Create the new sequelize_meta table if it does not exist\n reportDebug({\n namespace,\n message: 'Creating sequelize_meta table',\n data: { sqlType: process.env.SQL_TYPE }\n });\n await sequelize.query(createTableQuery, { type: QueryTypes.RAW });\n reportDebug({\n namespace,\n message: 'sequelize_meta table created successfully'\n });\n\n // Migrate the data from the old table to the new one if needed\n if (hasLegacySequelizeMeta) {\n reportDebug({\n namespace,\n message: 'Legacy metadata table found, migrating data'\n });\n\n const migrations = await sequelize.query<SequelizeMeta>(\n 'SELECT name FROM SequelizeMeta ORDER BY name',\n {\n type: QueryTypes.SELECT\n }\n );\n\n const insertQuery = `\n INSERT INTO sequelize_meta (name, version, createdAt, updatedAt) VALUES\n ${migrations\n .map((migration) => {\n switch (process.env.SQL_TYPE) {\n case 'mysql':\n case 'postgres':\n return `('${migration.name}', NULL, NOW(), NOW())`;\n case 'sqlite':\n return `('${migration.name}', NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`;\n case 'mssql':\n return `('${migration.name}', NULL, GETDATE(), GETDATE())`;\n default:\n throw new Error('Unsupported SQL type');\n }\n })\n .join(',')}\n `;\n\n await sequelize.query(insertQuery, { type: QueryTypes.INSERT });\n }\n }\n } catch (error) {\n reportError({\n namespace,\n message: 'Error in metadata migration',\n data: {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n sqlType: process.env.SQL_TYPE,\n sqlHost: process.env.SQL_HOST\n }\n });\n throw error;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.js","names":["_jsonwebtoken","require","_fs","_interopRequireDefault","_const","_EngineError","_KeySet","_WebError","_checkEnvironment","_envAssert","_report","keySet","exports","namespace","initKeySets","process","env","CHART","ECDSA_PUBLIC_KEY","EngineError","message","KeySet","file","AUTH_SERVICE_URL","internal","jwksPath","JWKS_PATH","promise","init","bind","Promise","all","shutdownKeySets","shutdown","jwtGetKey","header","callback","NODE_ENV","JWT_SECRET","kid","data","reportDebug","key","getKey","error","Error","WebError","statusCode","errorCode","jwtVerify","token","issuer","TokenIssuer","AUTH_SERVICE","algorithms","assertEnvironment","envAssert","isString","ACCESS_TOKEN_AUDIENCE","ACCESS_TOKEN_ISSUER","ACCESS_TOKEN_EXPIRATION_TIME","options","audience","resolve","reject","verify","result","undefined","generateJwtToken","user","signOptions","algorithm","expiresIn","parseInt","keyid","Object","keys","getKeys","privateKey","PRIVATE_KEY","PRIVATE_KEY_PATH","fs","readFileSync","String","sign"],"sources":["../../../src/utils/jwt/jwt.ts"],"sourcesContent":["import {\n verify,\n JwtHeader,\n SigningKeyCallback,\n Algorithm,\n VerifyOptions,\n sign\n} from 'jsonwebtoken';\nimport fs from 'fs';\nimport { UserTokenPayload } from './jwt.types';\nimport { TokenIssuer } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { KeySet } from 'entities/KeySet';\nimport { WebError } from 'entities/WebError';\nimport { assertEnvironment } from 'utils/checkEnvironment';\nimport { envAssert } from 'utils/envAssert';\nimport { reportDebug } from 'utils/report';\n\nexport let keySet: KeySet | undefined;\n\nconst namespace = 'engine:utils:jwt';\n\n/** Initiate key fetching mechanism */\nexport async function initKeySets(): Promise<void> {\n // Create the KeySet instance\n // The auth-service fetches its key from its disk and not from a network request\n // This prevents fetch failures the first time the auth-service is started\n if (process.env.CHART === 'auth-service') {\n if (!process.env.ECDSA_PUBLIC_KEY)\n throw new EngineError({\n message: 'Environment variable \"ECDSA_PUBLIC_KEY\" is not defined'\n });\n keySet = new KeySet(process.env.ECDSA_PUBLIC_KEY, { file: true });\n } else {\n if (process.env.AUTH_SERVICE_URL)\n keySet = new KeySet(\n `${process.env.AUTH_SERVICE_URL}/.well-known/jwks.json`,\n { internal: true }\n );\n else {\n // Use JWKS_PATH if set (e.g., by Secret Manager), otherwise fall back to local path\n const jwksPath = process.env.JWKS_PATH || './keys/jwks.json';\n keySet = new KeySet(jwksPath, { internal: true, file: true });\n }\n\n if (!keySet)\n throw new EngineError({\n message:\n 'Environment variable \"AUTH_SERVICE_URL\" is not defined or JWKS not found'\n });\n }\n const promise = [keySet.init.bind(keySet)()];\n\n await Promise.all(promise);\n}\n\n/** Stop fetching keys regularly */\nexport function shutdownKeySets(): void {\n if (keySet) keySet.shutdown.bind(keySet)();\n}\n\n/** Get the JWT public key */\nfunction jwtGetKey(header: JwtHeader, callback: SigningKeyCallback): void {\n // In test environment we return the symmetric signature secret\n if (process.env.NODE_ENV === 'test') {\n callback(null, process.env.JWT_SECRET);\n return;\n }\n // Check that KeySet has been initialized\n if (!keySet) {\n callback(new EngineError({ message: 'KeySet has not been initialized' }));\n return;\n }\n // Check that the token has a key ID\n if (!header.kid) {\n callback(\n new EngineError({\n message:\n 'Token has not key ID in header, impossible to match with known key',\n data: header\n })\n );\n return;\n }\n\n // In test environment we use a symmetrical secret bases signature\n if (process.env.NODE_ENV === 'test') {\n callback(null, process.env.JWT_SECRET);\n return;\n }\n reportDebug({\n namespace,\n message: `Looking for key with ID \"${header.kid}\"`\n });\n // Go through each key set to check if the token's key is in one of them\n let key;\n try {\n key = keySet.getKey(header.kid);\n } catch (error: Error | null | unknown) {\n callback(error instanceof Error ? error : null);\n return;\n }\n\n if (key) {\n reportDebug({ namespace, message: `Found key with ID \"${header.kid}\"` });\n callback(null, key);\n return;\n }\n callback(\n new WebError({\n statusCode: 401,\n errorCode: 'unauthorized',\n message: 'Could not find the tokens key in any key set',\n data: { kid: header.kid }\n })\n );\n}\n\n/** Verify an user Json Web Token */\nexport async function jwtVerify(\n token: string,\n issuer: TokenIssuer = TokenIssuer.AUTH_SERVICE\n): Promise<UserTokenPayload> {\n let algorithms = ['ES256' as Algorithm];\n if (process.env.NODE_ENV === 'test') {\n assertEnvironment({ JWT_SECRET: envAssert.isString() });\n algorithms = ['HS256' as Algorithm];\n }\n assertEnvironment({\n ACCESS_TOKEN_AUDIENCE: envAssert.isString(),\n ACCESS_TOKEN_ISSUER: envAssert.isString(),\n ACCESS_TOKEN_EXPIRATION_TIME: envAssert.isString()\n });\n let options: VerifyOptions | undefined;\n\n switch (issuer) {\n case TokenIssuer.AUTH_SERVICE:\n options = {\n audience: [process.env.ACCESS_TOKEN_AUDIENCE as string],\n issuer: [process.env.ACCESS_TOKEN_ISSUER as string],\n algorithms\n };\n break;\n default:\n throw new EngineError({\n message: `Invalid token issuer specified \"${issuer as string}\"`\n });\n }\n\n return new Promise<UserTokenPayload>((resolve, reject) => {\n verify(token, jwtGetKey, options, (error, result) => {\n if (error) {\n reject(\n new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Invalid token supplied',\n error: error instanceof Error ? error : undefined\n })\n );\n return;\n }\n resolve(result as UserTokenPayload);\n });\n });\n}\n\nexport function generateJwtToken(user: unknown) {\n const signOptions = {\n algorithm: 'ES256' as const, // or 'ES256' as Algorithm\n expiresIn: process.env.ACCESS_TOKEN_EXPIRATION_TIME\n ? parseInt(process.env.ACCESS_TOKEN_EXPIRATION_TIME, 10)\n : 3600,\n issuer: process.env.ACCESS_TOKEN_ISSUER,\n audience: process.env.ACCESS_TOKEN_AUDIENCE,\n keyid: Object.keys(keySet?.getKeys() ?? {})[0]\n };\n\n // Get private key - can be either the key content directly or a file path\n let privateKey: string;\n \n if (process.env.PRIVATE_KEY) {\n // Direct key content in environment variable\n privateKey = process.env.PRIVATE_KEY;\n } else if (process.env.PRIVATE_KEY_PATH) {\n // File path in environment variable - read the file\n try {\n privateKey = fs.readFileSync(process.env.PRIVATE_KEY_PATH, 'utf8');\n } catch (error) {\n throw new EngineError({\n message: `Failed to read private key from path: ${process.env.PRIVATE_KEY_PATH}`,\n data: { error: error instanceof Error ? error.message : String(error) }\n });\n }\n } else {\n throw new EngineError({ \n message: 'Neither PRIVATE_KEY nor PRIVATE_KEY_PATH environment variable is set' \n });\n }\n\n const token = sign({ user }, privateKey, signOptions);\n\n return token;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"jwt.js","names":["_jsonwebtoken","require","_fs","_interopRequireDefault","_const","_EngineError","_KeySet","_WebError","_checkEnvironment","_envAssert","_report","keySet","exports","namespace","initKeySets","process","env","CHART","ECDSA_PUBLIC_KEY","EngineError","message","KeySet","file","AUTH_SERVICE_URL","internal","jwksPath","JWKS_PATH","promise","init","bind","Promise","all","shutdownKeySets","shutdown","jwtGetKey","header","callback","NODE_ENV","JWT_SECRET","kid","data","reportDebug","key","getKey","error","Error","WebError","statusCode","errorCode","jwtVerify","token","issuer","TokenIssuer","AUTH_SERVICE","algorithms","assertEnvironment","envAssert","isString","ACCESS_TOKEN_AUDIENCE","ACCESS_TOKEN_ISSUER","ACCESS_TOKEN_EXPIRATION_TIME","options","audience","resolve","reject","verify","result","undefined","generateJwtToken","user","signOptions","algorithm","expiresIn","parseInt","keyid","Object","keys","getKeys","privateKey","PRIVATE_KEY","PRIVATE_KEY_PATH","fs","readFileSync","String","sign"],"sources":["../../../src/utils/jwt/jwt.ts"],"sourcesContent":["import {\n verify,\n JwtHeader,\n SigningKeyCallback,\n Algorithm,\n VerifyOptions,\n sign\n} from 'jsonwebtoken';\nimport fs from 'fs';\nimport { UserTokenPayload } from './jwt.types';\nimport { TokenIssuer } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { KeySet } from 'entities/KeySet';\nimport { WebError } from 'entities/WebError';\nimport { assertEnvironment } from 'utils/checkEnvironment';\nimport { envAssert } from 'utils/envAssert';\nimport { reportDebug } from 'utils/report';\n\nexport let keySet: KeySet | undefined;\n\nconst namespace = 'engine:utils:jwt';\n\n/** Initiate key fetching mechanism */\nexport async function initKeySets(): Promise<void> {\n // Create the KeySet instance\n // The auth-service fetches its key from its disk and not from a network request\n // This prevents fetch failures the first time the auth-service is started\n if (process.env.CHART === 'auth-service') {\n if (!process.env.ECDSA_PUBLIC_KEY)\n throw new EngineError({\n message: 'Environment variable \"ECDSA_PUBLIC_KEY\" is not defined'\n });\n keySet = new KeySet(process.env.ECDSA_PUBLIC_KEY, { file: true });\n } else {\n if (process.env.AUTH_SERVICE_URL)\n keySet = new KeySet(\n `${process.env.AUTH_SERVICE_URL}/.well-known/jwks.json`,\n { internal: true }\n );\n else {\n // Use JWKS_PATH if set (e.g., by Secret Manager), otherwise fall back to local path\n const jwksPath = process.env.JWKS_PATH || './keys/jwks.json';\n keySet = new KeySet(jwksPath, { internal: true, file: true });\n }\n\n if (!keySet)\n throw new EngineError({\n message:\n 'Environment variable \"AUTH_SERVICE_URL\" is not defined or JWKS not found'\n });\n }\n const promise = [keySet.init.bind(keySet)()];\n\n await Promise.all(promise);\n}\n\n/** Stop fetching keys regularly */\nexport function shutdownKeySets(): void {\n if (keySet) keySet.shutdown.bind(keySet)();\n}\n\n/** Get the JWT public key */\nfunction jwtGetKey(header: JwtHeader, callback: SigningKeyCallback): void {\n // In test environment we return the symmetric signature secret\n if (process.env.NODE_ENV === 'test') {\n callback(null, process.env.JWT_SECRET);\n return;\n }\n // Check that KeySet has been initialized\n if (!keySet) {\n callback(new EngineError({ message: 'KeySet has not been initialized' }));\n return;\n }\n // Check that the token has a key ID\n if (!header.kid) {\n callback(\n new EngineError({\n message:\n 'Token has not key ID in header, impossible to match with known key',\n data: header\n })\n );\n return;\n }\n\n // In test environment we use a symmetrical secret bases signature\n if (process.env.NODE_ENV === 'test') {\n callback(null, process.env.JWT_SECRET);\n return;\n }\n reportDebug({\n namespace,\n message: `Looking for key with ID \"${header.kid}\"`\n });\n // Go through each key set to check if the token's key is in one of them\n let key;\n try {\n key = keySet.getKey(header.kid);\n } catch (error: Error | null | unknown) {\n callback(error instanceof Error ? error : null);\n return;\n }\n\n if (key) {\n reportDebug({ namespace, message: `Found key with ID \"${header.kid}\"` });\n callback(null, key);\n return;\n }\n callback(\n new WebError({\n statusCode: 401,\n errorCode: 'unauthorized',\n message: 'Could not find the tokens key in any key set',\n data: { kid: header.kid }\n })\n );\n}\n\n/** Verify an user Json Web Token */\nexport async function jwtVerify(\n token: string,\n issuer: TokenIssuer = TokenIssuer.AUTH_SERVICE\n): Promise<UserTokenPayload> {\n let algorithms = ['ES256' as Algorithm];\n if (process.env.NODE_ENV === 'test') {\n assertEnvironment({ JWT_SECRET: envAssert.isString() });\n algorithms = ['HS256' as Algorithm];\n }\n assertEnvironment({\n ACCESS_TOKEN_AUDIENCE: envAssert.isString(),\n ACCESS_TOKEN_ISSUER: envAssert.isString(),\n ACCESS_TOKEN_EXPIRATION_TIME: envAssert.isString()\n });\n let options: VerifyOptions | undefined;\n\n switch (issuer) {\n case TokenIssuer.AUTH_SERVICE:\n options = {\n audience: [process.env.ACCESS_TOKEN_AUDIENCE as string],\n issuer: [process.env.ACCESS_TOKEN_ISSUER as string],\n algorithms\n };\n break;\n default:\n throw new EngineError({\n message: `Invalid token issuer specified \"${issuer as string}\"`\n });\n }\n\n return new Promise<UserTokenPayload>((resolve, reject) => {\n verify(token, jwtGetKey, options, (error, result) => {\n if (error) {\n reject(\n new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Invalid token supplied',\n error: error instanceof Error ? error : undefined\n })\n );\n return;\n }\n resolve(result as UserTokenPayload);\n });\n });\n}\n\nexport function generateJwtToken(user: unknown) {\n const signOptions = {\n algorithm: 'ES256' as const, // or 'ES256' as Algorithm\n expiresIn: process.env.ACCESS_TOKEN_EXPIRATION_TIME\n ? parseInt(process.env.ACCESS_TOKEN_EXPIRATION_TIME, 10)\n : 3600,\n issuer: process.env.ACCESS_TOKEN_ISSUER,\n audience: process.env.ACCESS_TOKEN_AUDIENCE,\n keyid: Object.keys(keySet?.getKeys() ?? {})[0]\n };\n\n // Get private key - can be either the key content directly or a file path\n let privateKey: string;\n\n if (process.env.PRIVATE_KEY) {\n // Direct key content in environment variable\n privateKey = process.env.PRIVATE_KEY;\n } else if (process.env.PRIVATE_KEY_PATH) {\n // File path in environment variable - read the file\n try {\n privateKey = fs.readFileSync(process.env.PRIVATE_KEY_PATH, 'utf8');\n } catch (error) {\n throw new EngineError({\n message: `Failed to read private key from path: ${process.env.PRIVATE_KEY_PATH}`,\n data: { error: error instanceof Error ? error.message : String(error) }\n });\n }\n } else {\n throw new EngineError({\n message:\n 'Neither PRIVATE_KEY nor PRIVATE_KEY_PATH environment variable is set'\n });\n }\n\n const token = sign({ user }, privateKey, signOptions);\n\n return token;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.types.js","names":[],"sources":["../../../src/utils/jwt/jwt.types.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"jwt.types.js","names":[],"sources":["../../../src/utils/jwt/jwt.types.ts"],"sourcesContent":["/** Content of the payload of user authentication tokens */\nexport interface UserTokenPayload {\n /** ID of the user */\n sub: string;\n /** URL of the service that issued the token */\n iss: string;\n /** URL of the services that can consume the token */\n aud: Array<string> | string;\n /** Unique ID of the token */\n jti: string;\n /** ID of the device the token was issued to */\n dev: string;\n /** Timestamp at which the token will expire */\n exp: number;\n /** List of permissions that the user has (only on the admin API) */\n per?: Array<string> | string;\n /** User */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n user: Record<string, any> | undefined;\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","names":["_crypto","require","_callsite","_interopRequireDefault","_jsonStringifySafe","_const","INSTANCE_ID","exports","randomUUID","colors","reset","bright","dim","red","green","yellow","blue","magenta","cyan","white","gray","getSeverityColor","severity","LogSeverity","DEBUG","INFO","WARNING","ERROR","CRITICAL","formatTime","date","now","Date","toTimeString","split","formatLocalLog","severityOrEntry","message","undefined","time","severityColor","useColors","process","env","NODE_ENV","output","padEnd","console","log","entry","showDetailedLogs","DETAILED_LOGS","parts","push","join","errorType","errorCode","statusCode","errorParts","statusColor","length","context","httpRequest","req","method","url","stack_trace","data","Object","keys","JSON","stringify","fileName","lineNumber","isLocalDevelopment","LOG_FORMAT","KUBERNETES_POD_NAME","CLOUD_RUN_JOB","SENSITIVE_KEY_PATTERN","REDACTED","MAX_REDACT_DEPTH","redactSensitive","value","depth","seen","WeakSet","has","add","Array","isArray","map","item","prototype","getPrototypeOf","result","key","entries","test","call","callsite","fullEntry","getLineNumber","getFileName","replace","serviceContext","service","CHART","HOSTNAME","version","BUILD_ID","environment","instance","SILENCE_REPORT","dir","formattedLog","error"],"sources":["../../../src/utils/report/output.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport callsite from 'callsite';\nimport stringify from 'json-stringify-safe';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { LogSeverity } from 'const';\n\n// NOTE: Server instance id (helpful for distributed logs)\nexport const INSTANCE_ID = randomUUID();\n\n// ANSI color codes for terminal output\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m'\n};\n\n/**\n * Get color for log severity level\n */\nfunction getSeverityColor(severity?: string): string {\n switch (severity) {\n case LogSeverity.DEBUG:\n return colors.cyan;\n case LogSeverity.INFO:\n return colors.green;\n case LogSeverity.WARNING:\n return colors.yellow;\n case LogSeverity.ERROR:\n return colors.red;\n case LogSeverity.CRITICAL:\n return `${colors.bright}${colors.red}`;\n default:\n return colors.white;\n }\n}\n\n/**\n * Format timestamp as HH:MM:SS\n */\nexport function formatTime(date?: Date): string {\n const now = date || new Date();\n return now.toTimeString().split(' ')[0];\n}\n\n/**\n * Format log entry for human-readable local development output\n */\nexport function formatLocalLog(severity: LogSeverity | string, message: string): void;\nexport function formatLocalLog(entry: FullLogEntry): string;\nexport function formatLocalLog(severityOrEntry: LogSeverity | string | FullLogEntry, message?: string): string | void {\n // Handle overloaded signature for testing\n if (typeof severityOrEntry === 'string' && message !== undefined) {\n const time = formatTime();\n const severityColor = getSeverityColor(severityOrEntry);\n const useColors = process.env.NODE_ENV !== 'production';\n \n const output = useColors \n ? `${colors.gray}[${time}]${colors.reset} ${severityColor}${severityOrEntry.padEnd(8)}${colors.reset} ${message}`\n : `[${time}] ${severityOrEntry.padEnd(8)} ${message}`;\n \n console.log(output);\n return;\n }\n \n // Original function implementation\n const entry = severityOrEntry as FullLogEntry;\n const time = formatTime();\n const severity = entry.severity || 'INFO';\n const severityColor = getSeverityColor(severity);\n const showDetailedLogs = process.env.DETAILED_LOGS === 'true';\n \n const parts: string[] = [];\n \n // Timestamp and severity\n parts.push(\n `${colors.gray}[${time}]${colors.reset} ${severityColor}${severity.padEnd(8)}${colors.reset}`\n );\n \n // Message\n if (entry.message) {\n parts.push(`${entry.message}`);\n }\n \n let output = parts.join(' ');\n \n // Error details (compact format)\n if (entry.errorType || entry.errorCode || entry.statusCode) {\n const errorParts: string[] = [];\n if (entry.errorCode) errorParts.push(`${colors.red}${entry.errorCode}${colors.reset}`);\n if (entry.statusCode) {\n const statusColor = entry.statusCode >= 500 ? colors.red : entry.statusCode >= 400 ? colors.yellow : colors.green;\n errorParts.push(`${statusColor}${entry.statusCode}${colors.reset}`);\n }\n if (errorParts.length > 0) {\n output += ` ${colors.dim}[${errorParts.join(' ')}]${colors.reset}`;\n }\n }\n \n // HTTP request context (compact)\n if (entry.context?.httpRequest) {\n const req = entry.context.httpRequest;\n output += ` ${colors.dim}${req.method} ${req.url}${colors.reset}`;\n }\n \n // Stack trace (only in detailed mode)\n if (showDetailedLogs && entry.stack_trace) {\n output += `\\n${colors.gray}Stack Trace:${colors.reset}\\n${colors.dim}${entry.stack_trace}${colors.reset}`;\n }\n \n // Additional data (only in detailed mode or if no message)\n if (showDetailedLogs && entry.data && Object.keys(entry.data).length > 0) {\n output += `\\n${colors.cyan}Data:${colors.reset}\\n${colors.dim}${JSON.stringify(entry.data, null, 2)}${colors.reset}`;\n }\n \n // File location (only in detailed mode)\n if (showDetailedLogs && entry.fileName) {\n output += `\\n ${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`;\n }\n \n return output;\n}\n\n/**\n * Check if running in local development environment\n */\nfunction isLocalDevelopment(): boolean {\n // Allow forcing local format via environment variable\n if (process.env.LOG_FORMAT === 'local') return true;\n if (process.env.LOG_FORMAT === 'json') return false;\n \n return (\n process.env.NODE_ENV === 'development' ||\n process.env.NODE_ENV === 'dev' ||\n (!process.env.NODE_ENV && !process.env.KUBERNETES_POD_NAME && !process.env.CLOUD_RUN_JOB)\n );\n}\n\n/** Keys whose values must never be written to the logs */\nconst SENSITIVE_KEY_PATTERN =\n /^(authorization|proxy[-_]?authorization|cookie|set[-_]?cookie|password|passwd|pass|secret|client[-_]?secret|token|access[-_]?token|refresh[-_]?token|id[-_]?token|api[-_]?key|private[-_]?key|credentials?|otp)$/i;\nconst REDACTED = '[REDACTED]';\nconst MAX_REDACT_DEPTH = 10;\n\n/** Returns a copy of the value with sensitive fields masked */\nexport function redactSensitive(\n value: unknown,\n depth = 0,\n seen: WeakSet<object> = new WeakSet()\n): unknown {\n if (!value || typeof value !== 'object' || depth > MAX_REDACT_DEPTH)\n return value;\n if (seen.has(value)) return value;\n seen.add(value);\n if (Array.isArray(value))\n return value.map((item) => redactSensitive(item, depth + 1, seen));\n // Only walk plain objects, leave class instances (Errors, Buffers, Dates...) untouched\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return value;\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = SENSITIVE_KEY_PATTERN.test(key)\n ? REDACTED\n : redactSensitive(entry, depth + 1, seen);\n }\n return result;\n}\n\n/** Add metadata to the log entry and print it */\nexport function output(data: LogEntry): FullLogEntry {\n if (data.data !== undefined)\n data = { ...data, data: redactSensitive(data.data) };\n\n // Gather useful information about where the logger was called from\n const call = callsite()[2];\n\n // Append additional metadata to the log entry\n const fullEntry: FullLogEntry = {\n ...data,\n lineNumber: call.getLineNumber(),\n fileName: call\n .getFileName()\n .replace(/.*node_modules\\//, '')\n .replace(/.*src\\//, 'src/'),\n serviceContext: {\n service: process.env.CHART ?? process.env.HOSTNAME,\n version: process.env.BUILD_ID,\n environment: process.env.NODE_ENV,\n instance: process.env.KUBERNETES_POD_NAME ?? INSTANCE_ID\n }\n };\n\n // Ignore when silenced\n if (process.env.SILENCE_REPORT) return fullEntry;\n\n if (process.env.NODE_ENV === 'test') {\n // In test mode pretty print with full depth\n console.dir(fullEntry, { depth: 5 });\n } else if (isLocalDevelopment()) {\n // Local development: use formatted, colorized output\n const formattedLog = formatLocalLog(fullEntry);\n if (data.severity === LogSeverity.ERROR || data.severity === LogSeverity.CRITICAL || (data.statusCode && data.statusCode >= 500)) {\n console.error(formattedLog);\n } else {\n console.log(formattedLog);\n }\n } else {\n // Production/GCP: use JSON format for structured logging\n const entry = stringify(fullEntry);\n if (data.statusCode && data.statusCode >= 500) {\n console.error(entry);\n } else {\n console.log(entry);\n }\n }\n \n return fullEntry;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"output.js","names":["_crypto","require","_callsite","_interopRequireDefault","_jsonStringifySafe","_const","INSTANCE_ID","exports","randomUUID","colors","reset","bright","dim","red","green","yellow","blue","magenta","cyan","white","gray","getSeverityColor","severity","LogSeverity","DEBUG","INFO","WARNING","ERROR","CRITICAL","formatTime","date","now","Date","toTimeString","split","formatLocalLog","severityOrEntry","message","undefined","time","severityColor","useColors","process","env","NODE_ENV","output","padEnd","console","log","entry","showDetailedLogs","DETAILED_LOGS","parts","push","join","errorType","errorCode","statusCode","errorParts","statusColor","length","context","httpRequest","req","method","url","stack_trace","data","Object","keys","JSON","stringify","fileName","lineNumber","isLocalDevelopment","LOG_FORMAT","KUBERNETES_POD_NAME","CLOUD_RUN_JOB","SENSITIVE_KEY_PATTERN","REDACTED","MAX_REDACT_DEPTH","redactSensitive","value","depth","seen","WeakSet","has","add","Array","isArray","map","item","prototype","getPrototypeOf","result","key","entries","test","call","callsite","fullEntry","getLineNumber","getFileName","replace","serviceContext","service","CHART","HOSTNAME","version","BUILD_ID","environment","instance","SILENCE_REPORT","dir","formattedLog","error"],"sources":["../../../src/utils/report/output.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport callsite from 'callsite';\nimport stringify from 'json-stringify-safe';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { LogSeverity } from 'const';\n\n// NOTE: Server instance id (helpful for distributed logs)\nexport const INSTANCE_ID = randomUUID();\n\n// ANSI color codes for terminal output\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n white: '\\x1b[37m',\n gray: '\\x1b[90m'\n};\n\n/**\n * Get color for log severity level\n */\nfunction getSeverityColor(severity?: string): string {\n switch (severity) {\n case LogSeverity.DEBUG:\n return colors.cyan;\n case LogSeverity.INFO:\n return colors.green;\n case LogSeverity.WARNING:\n return colors.yellow;\n case LogSeverity.ERROR:\n return colors.red;\n case LogSeverity.CRITICAL:\n return `${colors.bright}${colors.red}`;\n default:\n return colors.white;\n }\n}\n\n/**\n * Format timestamp as HH:MM:SS\n */\nexport function formatTime(date?: Date): string {\n const now = date || new Date();\n return now.toTimeString().split(' ')[0];\n}\n\n/**\n * Format log entry for human-readable local development output\n */\nexport function formatLocalLog(\n severity: LogSeverity | string,\n message: string\n): void;\nexport function formatLocalLog(entry: FullLogEntry): string;\nexport function formatLocalLog(\n severityOrEntry: LogSeverity | string | FullLogEntry,\n message?: string\n): string | void {\n // Handle overloaded signature for testing\n if (typeof severityOrEntry === 'string' && message !== undefined) {\n const time = formatTime();\n const severityColor = getSeverityColor(severityOrEntry);\n const useColors = process.env.NODE_ENV !== 'production';\n\n const output = useColors\n ? `${colors.gray}[${time}]${colors.reset} ${severityColor}${severityOrEntry.padEnd(8)}${colors.reset} ${message}`\n : `[${time}] ${severityOrEntry.padEnd(8)} ${message}`;\n\n console.log(output);\n return;\n }\n\n // Original function implementation\n const entry = severityOrEntry as FullLogEntry;\n const time = formatTime();\n const severity = entry.severity || 'INFO';\n const severityColor = getSeverityColor(severity);\n const showDetailedLogs = process.env.DETAILED_LOGS === 'true';\n\n const parts: string[] = [];\n\n // Timestamp and severity\n parts.push(\n `${colors.gray}[${time}]${colors.reset} ${severityColor}${severity.padEnd(8)}${colors.reset}`\n );\n\n // Message\n if (entry.message) {\n parts.push(`${entry.message}`);\n }\n\n let output = parts.join(' ');\n\n // Error details (compact format)\n if (entry.errorType || entry.errorCode || entry.statusCode) {\n const errorParts: string[] = [];\n if (entry.errorCode)\n errorParts.push(`${colors.red}${entry.errorCode}${colors.reset}`);\n if (entry.statusCode) {\n const statusColor =\n entry.statusCode >= 500\n ? colors.red\n : entry.statusCode >= 400\n ? colors.yellow\n : colors.green;\n errorParts.push(`${statusColor}${entry.statusCode}${colors.reset}`);\n }\n if (errorParts.length > 0) {\n output += ` ${colors.dim}[${errorParts.join(' ')}]${colors.reset}`;\n }\n }\n\n // HTTP request context (compact)\n if (entry.context?.httpRequest) {\n const req = entry.context.httpRequest;\n output += ` ${colors.dim}${req.method} ${req.url}${colors.reset}`;\n }\n\n // Stack trace (only in detailed mode)\n if (showDetailedLogs && entry.stack_trace) {\n output += `\\n${colors.gray}Stack Trace:${colors.reset}\\n${colors.dim}${entry.stack_trace}${colors.reset}`;\n }\n\n // Additional data (only in detailed mode or if no message)\n if (showDetailedLogs && entry.data && Object.keys(entry.data).length > 0) {\n output += `\\n${colors.cyan}Data:${colors.reset}\\n${colors.dim}${JSON.stringify(entry.data, null, 2)}${colors.reset}`;\n }\n\n // File location (only in detailed mode)\n if (showDetailedLogs && entry.fileName) {\n output += `\\n ${colors.dim}${entry.fileName}:${entry.lineNumber || '?'}${colors.reset}`;\n }\n\n return output;\n}\n\n/**\n * Check if running in local development environment\n */\nfunction isLocalDevelopment(): boolean {\n // Allow forcing local format via environment variable\n if (process.env.LOG_FORMAT === 'local') return true;\n if (process.env.LOG_FORMAT === 'json') return false;\n\n return (\n process.env.NODE_ENV === 'development' ||\n process.env.NODE_ENV === 'dev' ||\n (!process.env.NODE_ENV &&\n !process.env.KUBERNETES_POD_NAME &&\n !process.env.CLOUD_RUN_JOB)\n );\n}\n\n/** Keys whose values must never be written to the logs */\nconst SENSITIVE_KEY_PATTERN =\n /^(authorization|proxy[-_]?authorization|cookie|set[-_]?cookie|password|passwd|pass|secret|client[-_]?secret|token|access[-_]?token|refresh[-_]?token|id[-_]?token|api[-_]?key|private[-_]?key|credentials?|otp)$/i;\nconst REDACTED = '[REDACTED]';\nconst MAX_REDACT_DEPTH = 10;\n\n/** Returns a copy of the value with sensitive fields masked */\nexport function redactSensitive(\n value: unknown,\n depth = 0,\n seen: WeakSet<object> = new WeakSet()\n): unknown {\n if (!value || typeof value !== 'object' || depth > MAX_REDACT_DEPTH)\n return value;\n if (seen.has(value)) return value;\n seen.add(value);\n if (Array.isArray(value))\n return value.map((item) => redactSensitive(item, depth + 1, seen));\n // Only walk plain objects, leave class instances (Errors, Buffers, Dates...) untouched\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return value;\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = SENSITIVE_KEY_PATTERN.test(key)\n ? REDACTED\n : redactSensitive(entry, depth + 1, seen);\n }\n return result;\n}\n\n/** Add metadata to the log entry and print it */\nexport function output(data: LogEntry): FullLogEntry {\n if (data.data !== undefined)\n data = { ...data, data: redactSensitive(data.data) };\n\n // Gather useful information about where the logger was called from\n const call = callsite()[2];\n\n // Append additional metadata to the log entry\n const fullEntry: FullLogEntry = {\n ...data,\n lineNumber: call.getLineNumber(),\n fileName: call\n .getFileName()\n .replace(/.*node_modules\\//, '')\n .replace(/.*src\\//, 'src/'),\n serviceContext: {\n service: process.env.CHART ?? process.env.HOSTNAME,\n version: process.env.BUILD_ID,\n environment: process.env.NODE_ENV,\n instance: process.env.KUBERNETES_POD_NAME ?? INSTANCE_ID\n }\n };\n\n // Ignore when silenced\n if (process.env.SILENCE_REPORT) return fullEntry;\n\n if (process.env.NODE_ENV === 'test') {\n // In test mode pretty print with full depth\n console.dir(fullEntry, { depth: 5 });\n } else if (isLocalDevelopment()) {\n // Local development: use formatted, colorized output\n const formattedLog = formatLocalLog(fullEntry);\n if (\n data.severity === LogSeverity.ERROR ||\n data.severity === LogSeverity.CRITICAL ||\n (data.statusCode && data.statusCode >= 500)\n ) {\n console.error(formattedLog);\n } else {\n console.log(formattedLog);\n }\n } else {\n // Production/GCP: use JSON format for structured logging\n const entry = stringify(fullEntry);\n if (data.statusCode && data.statusCode >= 500) {\n console.error(entry);\n } else {\n console.log(entry);\n }\n }\n\n return fullEntry;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","names":["_output","require","_const","_EngineError","_WebError","reportInfo","data","output","severity","LogSeverity","INFO","message","reportError","error","request","logEntry","Error","stack_trace","stack","ERROR","CRITICAL","EngineError","errorType","constructor","name","WebError","statusCode","undefined","errorCode","context","user","id","hosts","join","httpRequest","url","originalUrl","method","referrer","header","userAgent","remoteIp","ip","responseStatusCode","NAMESPACE_SELECTORS","exports","initNamespaceSelector","process","env","DEBUG","split","map","namespace","RegExp","replace","resetNamespaceSelector","debugNamespace","reportDebug","isEngineReport","startsWith","match","some","selector","test","spaces","prefix","length","setNameSpace","globalNamespace","clearNamespace"],"sources":["../../../src/utils/report/report.ts"],"sourcesContent":["import { Request } from 'express';\nimport { output } from './output';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { DebugLogEntry, InfoLogEntry } from './report.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { WebError } from 'entities/WebError';\nimport {} from 'middleware/authHmac/authHmac.types';\nimport {} from 'middleware/authJwt/authJwt.types';\nimport {} from 'middleware/authTls/authTls.types';\n\n/** Default generic logger */\nexport function reportInfo(data: InfoLogEntry | string): FullLogEntry {\n return output({\n severity: LogSeverity.INFO,\n ...(typeof data === 'string' ? { message: data } : data)\n });\n}\n\n/** Error specific logger */\nexport function reportError(\n error: unknown | Error | EngineError | WebError,\n request?: Request\n): FullLogEntry {\n let logEntry: LogEntry =\n error instanceof Error\n ? {\n message: error.message,\n stack_trace: error.stack,\n severity: LogSeverity.ERROR\n }\n : {\n message: 'An unknown error occurred',\n data: error,\n severity: LogSeverity.CRITICAL\n };\n\n if (error instanceof EngineError) {\n logEntry = {\n ...logEntry,\n severity: error.severity,\n errorType: error.constructor.name,\n data: error.data,\n '@type':\n !(error instanceof WebError) || error.statusCode >= 500\n ? 'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent'\n : undefined\n };\n }\n\n if (error instanceof WebError) {\n logEntry = {\n ...logEntry,\n errorCode: error.errorCode,\n statusCode: error.statusCode\n };\n }\n\n if (request) {\n logEntry = {\n ...logEntry,\n context: {\n user
|
|
1
|
+
{"version":3,"file":"report.js","names":["_output","require","_const","_EngineError","_WebError","reportInfo","data","output","severity","LogSeverity","INFO","message","reportError","error","request","logEntry","Error","stack_trace","stack","ERROR","CRITICAL","EngineError","errorType","constructor","name","WebError","statusCode","undefined","errorCode","context","user","id","hosts","join","httpRequest","url","originalUrl","method","referrer","header","userAgent","remoteIp","ip","responseStatusCode","NAMESPACE_SELECTORS","exports","initNamespaceSelector","process","env","DEBUG","split","map","namespace","RegExp","replace","resetNamespaceSelector","debugNamespace","reportDebug","isEngineReport","startsWith","match","some","selector","test","spaces","prefix","length","setNameSpace","globalNamespace","clearNamespace"],"sources":["../../../src/utils/report/report.ts"],"sourcesContent":["import { Request } from 'express';\nimport { output } from './output';\nimport { LogEntry, FullLogEntry } from './output.types';\nimport { DebugLogEntry, InfoLogEntry } from './report.types';\nimport { LogSeverity } from 'const';\nimport { EngineError } from 'entities/EngineError';\nimport { WebError } from 'entities/WebError';\nimport {} from 'middleware/authHmac/authHmac.types';\nimport {} from 'middleware/authJwt/authJwt.types';\nimport {} from 'middleware/authTls/authTls.types';\n\n/** Default generic logger */\nexport function reportInfo(data: InfoLogEntry | string): FullLogEntry {\n return output({\n severity: LogSeverity.INFO,\n ...(typeof data === 'string' ? { message: data } : data)\n });\n}\n\n/** Error specific logger */\nexport function reportError(\n error: unknown | Error | EngineError | WebError,\n request?: Request\n): FullLogEntry {\n let logEntry: LogEntry =\n error instanceof Error\n ? {\n message: error.message,\n stack_trace: error.stack,\n severity: LogSeverity.ERROR\n }\n : {\n message: 'An unknown error occurred',\n data: error,\n severity: LogSeverity.CRITICAL\n };\n\n if (error instanceof EngineError) {\n logEntry = {\n ...logEntry,\n severity: error.severity,\n errorType: error.constructor.name,\n data: error.data,\n '@type':\n !(error instanceof WebError) || error.statusCode >= 500\n ? 'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent'\n : undefined\n };\n }\n\n if (error instanceof WebError) {\n logEntry = {\n ...logEntry,\n errorCode: error.errorCode,\n statusCode: error.statusCode\n };\n }\n\n if (request) {\n logEntry = {\n ...logEntry,\n context: {\n user: request.user?.id ?? request.hosts?.join(','),\n httpRequest: {\n url: request.originalUrl,\n method: request.method,\n referrer: request.header('Referer'),\n userAgent: request.header('User-Agent'),\n remoteIp: request.ip,\n responseStatusCode:\n error instanceof WebError ? error.statusCode : undefined\n }\n }\n };\n }\n\n return output(logEntry);\n}\n\nexport let NAMESPACE_SELECTORS: Array<RegExp> | undefined;\n\n/**\n * Generate the namespace selectors based on the DEBUG environment variable\n */\nfunction initNamespaceSelector(): void {\n if (process.env.DEBUG) {\n NAMESPACE_SELECTORS = process.env.DEBUG.split(',').map(\n (namespace) => new RegExp(`^${namespace.replace(/\\*/g, '.*?')}$`)\n );\n }\n}\n\n/**\n * Reset the namespace selectors\n */\nexport function resetNamespaceSelector(): void {\n NAMESPACE_SELECTORS = undefined;\n}\n\nlet debugNamespace: string | undefined;\n\n/**\n * Log a message for debugging purposes, based on a namespace specified in an environment variable\n * @param data - Debug log entry data\n * @returns The full log entry if namespace matches, undefined otherwise\n */\nexport function reportDebug(data: DebugLogEntry): FullLogEntry | undefined {\n if (!NAMESPACE_SELECTORS) {\n initNamespaceSelector();\n }\n\n let { namespace } = data;\n const isEngineReport = namespace?.startsWith('engine') ?? false;\n\n if (debugNamespace && !isEngineReport && namespace) {\n namespace = `${debugNamespace}:${namespace}`;\n }\n\n const match =\n namespace &&\n NAMESPACE_SELECTORS &&\n NAMESPACE_SELECTORS.some((selector) => selector.test(namespace));\n\n if (!match) return undefined;\n\n // Generate a prefix with the rightmost part of the namespace\n const spaces = namespace.split(':');\n const prefix = spaces[spaces.length - 1];\n\n return output({\n severity: LogSeverity.DEBUG,\n ...data,\n message: `[${prefix}] ${data.message}`\n });\n}\n\n/**\n * Specify a global debugging namespace\n * @param globalNamespace - The namespace to set globally\n */\nreportDebug.setNameSpace = function (globalNamespace: string): void {\n debugNamespace = globalNamespace;\n};\n\n/**\n * Remove any defined global namespace\n */\nreportDebug.clearNamespace = function (): void {\n debugNamespace = undefined;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semverCompare.js","names":["_validator","_interopRequireDefault","require","_EngineError","SEMVER_REGEX","semverCompare","v1","v2","match1","match2","map","v","match","EngineError","message","data","major1","minor1","patch1","preType1","preVersion1","major2","minor2","patch2","preType2","preVersion2","group","item","validator","isInt","parseInt"],"sources":["../../../src/utils/semverCompare/semverCompare.ts"],"sourcesContent":["import validator from 'validator';\nimport { EngineError } from 'entities/EngineError';\n\n// Regex to validate our SemVer style and capture the different parts\nconst SEMVER_REGEX =\n /^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-(?:(alpha|beta|rc)(?:\\.(0|[1-9]\\d*))))?$/;\n\n/**\n * Comparison function for our SemVer strings, includes support for pre-releases\n * @param v1 - First version string to compare\n * @param v2 - Second version string to compare\n * @returns -1 if v1 < v2, 0 if v1 = v2, +1 if v1 > v2\n */\nexport function semverCompare(v1: string, v2: string): 1 | -1 | 0 {\n const [match1, match2] = [v1, v2].map((v) => v.match(SEMVER_REGEX));\n
|
|
1
|
+
{"version":3,"file":"semverCompare.js","names":["_validator","_interopRequireDefault","require","_EngineError","SEMVER_REGEX","semverCompare","v1","v2","match1","match2","map","v","match","EngineError","message","data","major1","minor1","patch1","preType1","preVersion1","major2","minor2","patch2","preType2","preVersion2","group","item","validator","isInt","parseInt"],"sources":["../../../src/utils/semverCompare/semverCompare.ts"],"sourcesContent":["import validator from 'validator';\nimport { EngineError } from 'entities/EngineError';\n\n// Regex to validate our SemVer style and capture the different parts\nconst SEMVER_REGEX =\n /^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-(?:(alpha|beta|rc)(?:\\.(0|[1-9]\\d*))))?$/;\n\n/**\n * Comparison function for our SemVer strings, includes support for pre-releases\n * @param v1 - First version string to compare\n * @param v2 - Second version string to compare\n * @returns -1 if v1 < v2, 0 if v1 = v2, +1 if v1 > v2\n */\nexport function semverCompare(v1: string, v2: string): 1 | -1 | 0 {\n const [match1, match2] = [v1, v2].map((v) => v.match(SEMVER_REGEX));\n\n if (!match1 || !match2) {\n throw new EngineError({\n message: 'Provided invalid SemVer string, cannot compare',\n data: { v1, v2 }\n });\n }\n\n const [\n [, major1, minor1, patch1, preType1, preVersion1],\n [, major2, minor2, patch2, preType2, preVersion2]\n ] = [match1, match2].map((group) =>\n // Parse numeric values\n group.map((item) =>\n item && validator.isInt(item) ? parseInt(item, 10) : item\n )\n );\n\n // Compare majors first\n if (major1 < major2) return -1;\n if (major1 > major2) return 1;\n\n // Compare minors second\n if (minor1 < minor2) return -1;\n if (minor1 > minor2) return 1;\n\n // Compare patch third\n if (patch1 < patch2) return -1;\n if (patch1 > patch2) return 1;\n\n // Compare pre-release type\n // Release > pre-release\n if (!preType1 && !preType2) return 0;\n if (preType1 && !preType2) return -1;\n if (!preType1 && preType2) return 1;\n\n // RC > Beta > Alpha\n if (preType1 !== 'rc' && preType2 === 'rc') return -1;\n if (preType1 === 'rc' && preType2 !== 'rc') return 1;\n if (preType1 !== 'beta' && preType2 === 'beta') return -1;\n if (preType1 === 'beta' && preType2 !== 'beta') return 1;\n\n // Finally compare the pre-release versions\n if (preVersion1 < preVersion2) return -1;\n if (preVersion1 > preVersion2) return 1;\n\n return 0;\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,UAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA;AACA,MAAME,YAAY,GAChB,yFAAyF;;AAE3F;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,aAAaA,CAACC,EAAU,EAAEC,EAAU,EAAc;EAChE,MAAM,CAACC,MAAM,EAAEC,MAAM,CAAC,GAAG,CAACH,EAAE,EAAEC,EAAE,CAAC,CAACG,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAACC,KAAK,CAACR,YAAY,CAAC,CAAC;EAEnE,IAAI,CAACI,MAAM,IAAI,CAACC,MAAM,EAAE;IACtB,MAAM,IAAII,wBAAW,CAAC;MACpBC,OAAO,EAAE,gDAAgD;MACzDC,IAAI,EAAE;QAAET,EAAE;QAAEC;MAAG;IACjB,CAAC,CAAC;EACJ;EAEA,MAAM,CACJ,GAAGS,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,WAAW,CAAC,EACjD,GAAGC,MAAM,EAAEC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,WAAW,CAAC,CAClD,GAAG,CAACjB,MAAM,EAAEC,MAAM,CAAC,CAACC,GAAG,CAAEgB,KAAK;EAC7B;EACAA,KAAK,CAAChB,GAAG,CAAEiB,IAAI,IACbA,IAAI,IAAIC,kBAAS,CAACC,KAAK,CAACF,IAAI,CAAC,GAAGG,QAAQ,CAACH,IAAI,EAAE,EAAE,CAAC,GAAGA,IACvD,CACF,CAAC;;EAED;EACA,IAAIX,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC,CAAC;EAC9B,IAAIL,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC;;EAE7B;EACA,IAAIJ,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC,CAAC;EAC9B,IAAIL,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC;;EAE7B;EACA,IAAIJ,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC,CAAC;EAC9B,IAAIL,MAAM,GAAGK,MAAM,EAAE,OAAO,CAAC;;EAE7B;EACA;EACA,IAAI,CAACJ,QAAQ,IAAI,CAACK,QAAQ,EAAE,OAAO,CAAC;EACpC,IAAIL,QAAQ,IAAI,CAACK,QAAQ,EAAE,OAAO,CAAC,CAAC;EACpC,IAAI,CAACL,QAAQ,IAAIK,QAAQ,EAAE,OAAO,CAAC;;EAEnC;EACA,IAAIL,QAAQ,KAAK,IAAI,IAAIK,QAAQ,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;EACrD,IAAIL,QAAQ,KAAK,IAAI,IAAIK,QAAQ,KAAK,IAAI,EAAE,OAAO,CAAC;EACpD,IAAIL,QAAQ,KAAK,MAAM,IAAIK,QAAQ,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC;EACzD,IAAIL,QAAQ,KAAK,MAAM,IAAIK,QAAQ,KAAK,MAAM,EAAE,OAAO,CAAC;;EAExD;EACA,IAAIJ,WAAW,GAAGK,WAAW,EAAE,OAAO,CAAC,CAAC;EACxC,IAAIL,WAAW,GAAGK,WAAW,EAAE,OAAO,CAAC;EAEvC,OAAO,CAAC;AACV","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verificationToken.js","names":["_crypto","require","_jsonwebtoken","_EngineError","_WebError","_checkEnvironment","_envAssert","DEFAULT_OTP_LENGTH","DEFAULT_EXPIRES_IN_SECONDS","DEFAULT_ISSUER","normalizeAction","action","EngineError","message","data","trim","toUpperCase","resolveOtpLength","length","undefined","Number","isInteger","resolveExpiresInSeconds","expiresInSeconds","getTokenSecret","secret","process","env","VERIFICATION_TOKEN_SECRET","assertEnvironment","envAssert","isString","getOtpSecret","VERIFICATION_TOKEN_OTP_SECRET","hashOtp","otp","createHmac","update","digest","safeEqual","a","b","bufferA","Buffer","from","bufferB","timingSafeEqual","generateOtp","index","randomInt","toString","buildIssuer","issuer","VERIFICATION_TOKEN_ISSUER","buildSignOptions","options","signOptions","algorithm","expiresIn","audience","VERIFICATION_TOKEN_AUDIENCE","normalizeAudience","Array","isArray","slice","buildVerifyOptions","verifyOptions","algorithms","normalizedAudience","createVerificationToken","otpLength","tokenSecret","otpSecret","payload","act","jti","randomUUID","sub","subject","token","sign","expiresAt","Date","now","verificationToken","exports","verifyVerificationToken","bypassSubject","VERIFICATION_BYPASS_SUBJECT","bypassOtp","VERIFICATION_BYPASS_OTP","iat","Math","floor","exp","iss","verify","error","WebError","errorCode","statusCode","Error","expected","actual","expectedHash"],"sources":["../../../src/utils/verificationToken/verificationToken.ts"],"sourcesContent":["import { randomInt, randomUUID, createHmac, timingSafeEqual } from 'crypto';\nimport { sign, verify, SignOptions, VerifyOptions } from 'jsonwebtoken';\nimport { EngineError } from 'entities/EngineError';\nimport { WebError } from 'entities/WebError';\nimport { assertEnvironment } from 'utils/checkEnvironment';\nimport { envAssert } from 'utils/envAssert';\nimport {\n VerificationTokenPayload,\n VerificationTokenOptions,\n VerificationTokenResult,\n VerifyVerificationTokenOptions\n} from './verificationToken.types';\n\nconst DEFAULT_OTP_LENGTH = 6;\nconst DEFAULT_EXPIRES_IN_SECONDS = 5 * 60;\nconst DEFAULT_ISSUER = 'node-server-engine';\n\nfunction normalizeAction(action: string): string {\n if (!action || typeof action !== 'string') {\n throw new EngineError({\n message: 'Verification token action must be a non-empty string',\n data: { action }\n });\n }\n return action.trim().toUpperCase();\n}\n\nfunction resolveOtpLength(length?: number): number {\n if (length === undefined) return DEFAULT_OTP_LENGTH;\n if (!Number.isInteger(length) || length < 4 || length > 10) {\n throw new EngineError({\n message: 'OTP length must be an integer between 4 and 10',\n data: { length }\n });\n }\n return length;\n}\n\nfunction resolveExpiresInSeconds(expiresInSeconds?: number): number {\n if (expiresInSeconds === undefined) return DEFAULT_EXPIRES_IN_SECONDS;\n if (!Number.isInteger(expiresInSeconds) || expiresInSeconds < 30) {\n throw new EngineError({\n message: 'Verification token expiration must be at least 30 seconds',\n data: { expiresInSeconds }\n });\n }\n return expiresInSeconds;\n}\n\nfunction getTokenSecret(): string {\n const secret = process.env.VERIFICATION_TOKEN_SECRET;\n if (!secret) {\n assertEnvironment({ VERIFICATION_TOKEN_SECRET: envAssert.isString() });\n }\n return secret as string;\n}\n\nfunction getOtpSecret(): string {\n return process.env.VERIFICATION_TOKEN_OTP_SECRET ?? getTokenSecret();\n}\n\nfunction hashOtp(otp: string, secret: string): string {\n return createHmac('sha256', secret).update(otp).digest('hex');\n}\n\n/** Constant time string comparison */\nfunction safeEqual(a: string, b: string): boolean {\n const bufferA = Buffer.from(a);\n const bufferB = Buffer.from(b);\n return bufferA.length === bufferB.length && timingSafeEqual(bufferA, bufferB);\n}\n\nfunction generateOtp(length: number): string {\n let otp = '';\n for (let index = 0; index < length; index += 1) {\n otp += randomInt(0, 10).toString();\n }\n return otp;\n}\n\nfunction buildIssuer(issuer?: string): string {\n return issuer ?? process.env.VERIFICATION_TOKEN_ISSUER ?? DEFAULT_ISSUER;\n}\n\nfunction buildSignOptions(options: VerificationTokenOptions): SignOptions {\n const signOptions: SignOptions = {\n algorithm: 'HS256',\n expiresIn: resolveExpiresInSeconds(options.expiresInSeconds),\n issuer: buildIssuer(options.issuer)\n };\n if (options.audience) {\n signOptions.audience = options.audience;\n } else if (process.env.VERIFICATION_TOKEN_AUDIENCE) {\n signOptions.audience = process.env.VERIFICATION_TOKEN_AUDIENCE;\n }\n return signOptions;\n}\n\nfunction normalizeAudience(\n audience?: string | string[]\n): VerifyOptions['audience'] | undefined {\n if (!audience) return undefined;\n if (Array.isArray(audience)) {\n if (audience.length === 0) return undefined;\n return [audience[0], ...audience.slice(1)];\n }\n return audience;\n}\n\nfunction buildVerifyOptions(options: VerifyVerificationTokenOptions): VerifyOptions {\n const verifyOptions: VerifyOptions = {\n algorithms: ['HS256'],\n issuer: buildIssuer(options.issuer)\n };\n const normalizedAudience = normalizeAudience(\n options.audience ?? process.env.VERIFICATION_TOKEN_AUDIENCE\n );\n if (normalizedAudience) verifyOptions.audience = normalizedAudience;\n return verifyOptions;\n}\n\nexport function createVerificationToken(\n options: VerificationTokenOptions\n): VerificationTokenResult {\n const action = normalizeAction(options.action);\n const otpLength = resolveOtpLength(options.otpLength);\n const tokenSecret = getTokenSecret();\n const otpSecret = getOtpSecret();\n const otp = generateOtp(otpLength);\n const signOptions = buildSignOptions(options);\n const payload: VerificationTokenPayload = {\n act: action,\n otp: hashOtp(otp, otpSecret),\n jti: randomUUID(),\n sub: options.subject\n };\n\n const token = sign(payload, tokenSecret, signOptions);\n const expiresInSeconds = signOptions.expiresIn as number;\n\n return {\n token,\n otp,\n expiresAt: Date.now() + expiresInSeconds * 1000,\n action\n };\n}\n\nexport const verificationToken = createVerificationToken;\n\nexport function verifyVerificationToken(\n token: string,\n options: VerifyVerificationTokenOptions = {}\n): VerificationTokenPayload {\n // Optional verification bypass for a single review account (e.g. app store review)\n // It is disabled unless both VERIFICATION_BYPASS_SUBJECT and VERIFICATION_BYPASS_OTP are explicitly set\n const bypassSubject = process.env.VERIFICATION_BYPASS_SUBJECT;\n const bypassOtp = process.env.VERIFICATION_BYPASS_OTP;\n if (\n bypassSubject &&\n bypassOtp &&\n options.subject === bypassSubject &&\n options.otp !== undefined &&\n safeEqual(options.otp, bypassOtp)\n ) {\n return {\n act: options.action ? normalizeAction(options.action) : 'TEST_VERIFICATION',\n otp: hashOtp(bypassOtp, getOtpSecret()),\n jti: 'test-verification-jti',\n sub: bypassSubject,\n iat: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + DEFAULT_EXPIRES_IN_SECONDS,\n iss: buildIssuer(options.issuer)\n } as VerificationTokenPayload;\n }\n\n const tokenSecret = getTokenSecret();\n let payload: VerificationTokenPayload;\n\n try {\n payload = verify(token, tokenSecret, buildVerifyOptions(options)) as VerificationTokenPayload;\n } catch (error: unknown) {\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Invalid verification token supplied',\n error: error instanceof Error ? error : undefined\n });\n }\n\n if (!payload?.act || !payload?.otp || !payload?.jti) {\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Malformed verification token payload'\n });\n }\n\n if (options.action) {\n const action = normalizeAction(options.action);\n if (payload.act !== action) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification action mismatch',\n data: { expected: action, actual: payload.act }\n });\n }\n }\n\n if (options.subject && payload.sub !== options.subject) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification subject mismatch',\n data: { expected: options.subject, actual: payload.sub }\n });\n }\n\n if (options.otp) {\n const otpSecret = getOtpSecret();\n const expectedHash = hashOtp(options.otp, otpSecret);\n if (!safeEqual(payload.otp, expectedHash)) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification OTP mismatch'\n });\n }\n }\n\n return payload;\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"verificationToken.js","names":["_crypto","require","_jsonwebtoken","_EngineError","_WebError","_checkEnvironment","_envAssert","DEFAULT_OTP_LENGTH","DEFAULT_EXPIRES_IN_SECONDS","DEFAULT_ISSUER","normalizeAction","action","EngineError","message","data","trim","toUpperCase","resolveOtpLength","length","undefined","Number","isInteger","resolveExpiresInSeconds","expiresInSeconds","getTokenSecret","secret","process","env","VERIFICATION_TOKEN_SECRET","assertEnvironment","envAssert","isString","getOtpSecret","VERIFICATION_TOKEN_OTP_SECRET","hashOtp","otp","createHmac","update","digest","safeEqual","a","b","bufferA","Buffer","from","bufferB","timingSafeEqual","generateOtp","index","randomInt","toString","buildIssuer","issuer","VERIFICATION_TOKEN_ISSUER","buildSignOptions","options","signOptions","algorithm","expiresIn","audience","VERIFICATION_TOKEN_AUDIENCE","normalizeAudience","Array","isArray","slice","buildVerifyOptions","verifyOptions","algorithms","normalizedAudience","createVerificationToken","otpLength","tokenSecret","otpSecret","payload","act","jti","randomUUID","sub","subject","token","sign","expiresAt","Date","now","verificationToken","exports","verifyVerificationToken","bypassSubject","VERIFICATION_BYPASS_SUBJECT","bypassOtp","VERIFICATION_BYPASS_OTP","iat","Math","floor","exp","iss","verify","error","WebError","errorCode","statusCode","Error","expected","actual","expectedHash"],"sources":["../../../src/utils/verificationToken/verificationToken.ts"],"sourcesContent":["import { randomInt, randomUUID, createHmac, timingSafeEqual } from 'crypto';\nimport { sign, verify, SignOptions, VerifyOptions } from 'jsonwebtoken';\nimport { EngineError } from 'entities/EngineError';\nimport { WebError } from 'entities/WebError';\nimport { assertEnvironment } from 'utils/checkEnvironment';\nimport { envAssert } from 'utils/envAssert';\nimport {\n VerificationTokenPayload,\n VerificationTokenOptions,\n VerificationTokenResult,\n VerifyVerificationTokenOptions\n} from './verificationToken.types';\n\nconst DEFAULT_OTP_LENGTH = 6;\nconst DEFAULT_EXPIRES_IN_SECONDS = 5 * 60;\nconst DEFAULT_ISSUER = 'node-server-engine';\n\nfunction normalizeAction(action: string): string {\n if (!action || typeof action !== 'string') {\n throw new EngineError({\n message: 'Verification token action must be a non-empty string',\n data: { action }\n });\n }\n return action.trim().toUpperCase();\n}\n\nfunction resolveOtpLength(length?: number): number {\n if (length === undefined) return DEFAULT_OTP_LENGTH;\n if (!Number.isInteger(length) || length < 4 || length > 10) {\n throw new EngineError({\n message: 'OTP length must be an integer between 4 and 10',\n data: { length }\n });\n }\n return length;\n}\n\nfunction resolveExpiresInSeconds(expiresInSeconds?: number): number {\n if (expiresInSeconds === undefined) return DEFAULT_EXPIRES_IN_SECONDS;\n if (!Number.isInteger(expiresInSeconds) || expiresInSeconds < 30) {\n throw new EngineError({\n message: 'Verification token expiration must be at least 30 seconds',\n data: { expiresInSeconds }\n });\n }\n return expiresInSeconds;\n}\n\nfunction getTokenSecret(): string {\n const secret = process.env.VERIFICATION_TOKEN_SECRET;\n if (!secret) {\n assertEnvironment({ VERIFICATION_TOKEN_SECRET: envAssert.isString() });\n }\n return secret as string;\n}\n\nfunction getOtpSecret(): string {\n return process.env.VERIFICATION_TOKEN_OTP_SECRET ?? getTokenSecret();\n}\n\nfunction hashOtp(otp: string, secret: string): string {\n return createHmac('sha256', secret).update(otp).digest('hex');\n}\n\n/** Constant time string comparison */\nfunction safeEqual(a: string, b: string): boolean {\n const bufferA = Buffer.from(a);\n const bufferB = Buffer.from(b);\n return bufferA.length === bufferB.length && timingSafeEqual(bufferA, bufferB);\n}\n\nfunction generateOtp(length: number): string {\n let otp = '';\n for (let index = 0; index < length; index += 1) {\n otp += randomInt(0, 10).toString();\n }\n return otp;\n}\n\nfunction buildIssuer(issuer?: string): string {\n return issuer ?? process.env.VERIFICATION_TOKEN_ISSUER ?? DEFAULT_ISSUER;\n}\n\nfunction buildSignOptions(options: VerificationTokenOptions): SignOptions {\n const signOptions: SignOptions = {\n algorithm: 'HS256',\n expiresIn: resolveExpiresInSeconds(options.expiresInSeconds),\n issuer: buildIssuer(options.issuer)\n };\n if (options.audience) {\n signOptions.audience = options.audience;\n } else if (process.env.VERIFICATION_TOKEN_AUDIENCE) {\n signOptions.audience = process.env.VERIFICATION_TOKEN_AUDIENCE;\n }\n return signOptions;\n}\n\nfunction normalizeAudience(\n audience?: string | string[]\n): VerifyOptions['audience'] | undefined {\n if (!audience) return undefined;\n if (Array.isArray(audience)) {\n if (audience.length === 0) return undefined;\n return [audience[0], ...audience.slice(1)];\n }\n return audience;\n}\n\nfunction buildVerifyOptions(\n options: VerifyVerificationTokenOptions\n): VerifyOptions {\n const verifyOptions: VerifyOptions = {\n algorithms: ['HS256'],\n issuer: buildIssuer(options.issuer)\n };\n const normalizedAudience = normalizeAudience(\n options.audience ?? process.env.VERIFICATION_TOKEN_AUDIENCE\n );\n if (normalizedAudience) verifyOptions.audience = normalizedAudience;\n return verifyOptions;\n}\n\nexport function createVerificationToken(\n options: VerificationTokenOptions\n): VerificationTokenResult {\n const action = normalizeAction(options.action);\n const otpLength = resolveOtpLength(options.otpLength);\n const tokenSecret = getTokenSecret();\n const otpSecret = getOtpSecret();\n const otp = generateOtp(otpLength);\n const signOptions = buildSignOptions(options);\n const payload: VerificationTokenPayload = {\n act: action,\n otp: hashOtp(otp, otpSecret),\n jti: randomUUID(),\n sub: options.subject\n };\n\n const token = sign(payload, tokenSecret, signOptions);\n const expiresInSeconds = signOptions.expiresIn as number;\n\n return {\n token,\n otp,\n expiresAt: Date.now() + expiresInSeconds * 1000,\n action\n };\n}\n\nexport const verificationToken = createVerificationToken;\n\nexport function verifyVerificationToken(\n token: string,\n options: VerifyVerificationTokenOptions = {}\n): VerificationTokenPayload {\n // Optional verification bypass for a single review account (e.g. app store review)\n // It is disabled unless both VERIFICATION_BYPASS_SUBJECT and VERIFICATION_BYPASS_OTP are explicitly set\n const bypassSubject = process.env.VERIFICATION_BYPASS_SUBJECT;\n const bypassOtp = process.env.VERIFICATION_BYPASS_OTP;\n if (\n bypassSubject &&\n bypassOtp &&\n options.subject === bypassSubject &&\n options.otp !== undefined &&\n safeEqual(options.otp, bypassOtp)\n ) {\n return {\n act: options.action\n ? normalizeAction(options.action)\n : 'TEST_VERIFICATION',\n otp: hashOtp(bypassOtp, getOtpSecret()),\n jti: 'test-verification-jti',\n sub: bypassSubject,\n iat: Math.floor(Date.now() / 1000),\n exp: Math.floor(Date.now() / 1000) + DEFAULT_EXPIRES_IN_SECONDS,\n iss: buildIssuer(options.issuer)\n } as VerificationTokenPayload;\n }\n\n const tokenSecret = getTokenSecret();\n let payload: VerificationTokenPayload;\n\n try {\n payload = verify(\n token,\n tokenSecret,\n buildVerifyOptions(options)\n ) as VerificationTokenPayload;\n } catch (error: unknown) {\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Invalid verification token supplied',\n error: error instanceof Error ? error : undefined\n });\n }\n\n if (!payload?.act || !payload?.otp || !payload?.jti) {\n throw new WebError({\n errorCode: 'unauthorized',\n statusCode: 401,\n message: 'Malformed verification token payload'\n });\n }\n\n if (options.action) {\n const action = normalizeAction(options.action);\n if (payload.act !== action) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification action mismatch',\n data: { expected: action, actual: payload.act }\n });\n }\n }\n\n if (options.subject && payload.sub !== options.subject) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification subject mismatch',\n data: { expected: options.subject, actual: payload.sub }\n });\n }\n\n if (options.otp) {\n const otpSecret = getOtpSecret();\n const expectedHash = hashOtp(options.otp, otpSecret);\n if (!safeEqual(payload.otp, expectedHash)) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification OTP mismatch'\n });\n }\n }\n\n return payload;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-server-engine",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Framework used to develop backend services. This package ships with a lot of features to standardize the creation of services, letting you focus on the business logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|