node-server-engine 1.1.6 → 1.1.8

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.
Files changed (65) hide show
  1. package/.env.example +0 -38
  2. package/.nycrc +9 -3
  3. package/README.md +2 -3
  4. package/dist/const/tokenIssuer.d.ts +2 -4
  5. package/dist/const/tokenIssuer.js +0 -1
  6. package/dist/const/tokenIssuer.js.map +1 -1
  7. package/dist/entities/Endpoint/Endpoint.types.d.ts +2 -19
  8. package/dist/entities/Endpoint/Endpoint.types.js +1 -8
  9. package/dist/entities/Endpoint/Endpoint.types.js.map +1 -1
  10. package/dist/entities/Server/Server.js +5 -0
  11. package/dist/entities/Server/Server.js.map +1 -1
  12. package/dist/middleware/index.d.ts +0 -1
  13. package/dist/middleware/index.js +0 -11
  14. package/dist/middleware/index.js.map +1 -1
  15. package/dist/utils/index.d.ts +0 -1
  16. package/dist/utils/index.js +0 -11
  17. package/dist/utils/index.js.map +1 -1
  18. package/dist/utils/jwt/jwt.d.ts +0 -1
  19. package/dist/utils/jwt/jwt.js +2 -23
  20. package/dist/utils/jwt/jwt.js.map +1 -1
  21. package/dist/utils/report/report.js +1 -2
  22. package/dist/utils/report/report.js.map +1 -1
  23. package/package.json +9 -7
  24. package/src/const/tokenIssuer.ts +1 -3
  25. package/src/entities/Endpoint/Endpoint.test.ts +0 -89
  26. package/src/entities/Endpoint/Endpoint.types.ts +3 -30
  27. package/src/entities/KeySet/KeySet.test.ts +1 -1
  28. package/src/entities/Server/Server.ts +9 -0
  29. package/src/middleware/index.ts +0 -1
  30. package/src/utils/index.ts +0 -1
  31. package/src/utils/jwt/jwt.test.ts +0 -13
  32. package/src/utils/jwt/jwt.ts +2 -25
  33. package/src/utils/report/report.ts +1 -2
  34. package/test/env.ts +0 -5
  35. package/test/hooks.ts +0 -2
  36. package/dist/middleware/authAdmin/authAdmin.d.ts +0 -4
  37. package/dist/middleware/authAdmin/authAdmin.js +0 -105
  38. package/dist/middleware/authAdmin/authAdmin.js.map +0 -1
  39. package/dist/middleware/authAdmin/authAdmin.types.d.ts +0 -16
  40. package/dist/middleware/authAdmin/authAdmin.types.js +0 -2
  41. package/dist/middleware/authAdmin/authAdmin.types.js.map +0 -1
  42. package/dist/middleware/authAdmin/index.d.ts +0 -2
  43. package/dist/middleware/authAdmin/index.js +0 -28
  44. package/dist/middleware/authAdmin/index.js.map +0 -1
  45. package/dist/utils/getDynamicLink/getDynamicLink.d.ts +0 -3
  46. package/dist/utils/getDynamicLink/getDynamicLink.js +0 -28
  47. package/dist/utils/getDynamicLink/getDynamicLink.js.map +0 -1
  48. package/dist/utils/getDynamicLink/getDynamicLink.types.d.ts +0 -10
  49. package/dist/utils/getDynamicLink/getDynamicLink.types.js +0 -2
  50. package/dist/utils/getDynamicLink/getDynamicLink.types.js.map +0 -1
  51. package/dist/utils/getDynamicLink/getDynamicLink.validate.d.ts +0 -2
  52. package/dist/utils/getDynamicLink/getDynamicLink.validate.js +0 -14
  53. package/dist/utils/getDynamicLink/getDynamicLink.validate.js.map +0 -1
  54. package/dist/utils/getDynamicLink/index.d.ts +0 -2
  55. package/dist/utils/getDynamicLink/index.js +0 -28
  56. package/dist/utils/getDynamicLink/index.js.map +0 -1
  57. package/src/middleware/authAdmin/authAdmin.test.ts +0 -199
  58. package/src/middleware/authAdmin/authAdmin.ts +0 -114
  59. package/src/middleware/authAdmin/authAdmin.types.ts +0 -19
  60. package/src/middleware/authAdmin/index.ts +0 -2
  61. package/src/utils/getDynamicLink/getDynamicLink.test.ts +0 -51
  62. package/src/utils/getDynamicLink/getDynamicLink.ts +0 -28
  63. package/src/utils/getDynamicLink/getDynamicLink.types.ts +0 -11
  64. package/src/utils/getDynamicLink/getDynamicLink.validate.ts +0 -6
  65. package/src/utils/getDynamicLink/index.ts +0 -2
@@ -4,7 +4,6 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.adminKeySet = void 0;
8
7
  exports.generateJwtToken = generateJwtToken;
9
8
  exports.initKeySets = initKeySets;
10
9
  exports.jwtVerify = jwtVerify;
@@ -20,7 +19,6 @@ var _checkEnvironment = require("../checkEnvironment");
20
19
  var _envAssert = require("../envAssert");
21
20
  var _report = require("../report");
22
21
  let keySet = exports.keySet = void 0;
23
- let adminKeySet = exports.adminKeySet = void 0;
24
22
  const namespace = 'engine:utils:jwt';
25
23
 
26
24
  /** Initiate key fetching mechanism */
@@ -47,22 +45,12 @@ async function initKeySets() {
47
45
  });
48
46
  }
49
47
  const promise = [keySet.init.bind(keySet)()];
50
-
51
- // Load the key set for the admin api
52
- if (!process.env.ADMIN_API_ECDSA_PUBLIC_KEY) throw new _EngineError.EngineError({
53
- message: "Admin API's authentication JWT signing public key is not defined"
54
- });
55
- exports.adminKeySet = adminKeySet = new _KeySet.KeySet(process.env.ADMIN_API_ECDSA_PUBLIC_KEY, {
56
- pem: true
57
- });
58
- promise.push(adminKeySet.init.bind(adminKeySet)());
59
48
  await Promise.all(promise);
60
49
  }
61
50
 
62
51
  /** Stop fetching keys regularly */
63
52
  function shutdownKeySets() {
64
53
  if (keySet) keySet.shutdown.bind(keySet)();
65
- if (adminKeySet) adminKeySet.shutdown.bind(adminKeySet)();
66
54
  }
67
55
 
68
56
  /** Get the JWT public key */
@@ -73,7 +61,7 @@ function jwtGetKey(header, callback) {
73
61
  return;
74
62
  }
75
63
  // Check that KeySet has been initialized
76
- if (!keySet || !adminKeySet) {
64
+ if (!keySet) {
77
65
  callback(new _EngineError.EngineError({
78
66
  message: 'KeySet has not been initialized'
79
67
  }));
@@ -134,9 +122,7 @@ async function jwtVerify(token, issuer = _const.TokenIssuer.AUTH_SERVICE) {
134
122
  }
135
123
  (0, _checkEnvironment.assertEnvironment)({
136
124
  ACCESS_TOKEN_AUDIENCE: _envAssert.envAssert.isString(),
137
- ACCESS_TOKEN_ISSUER: _envAssert.envAssert.isString(),
138
- ADMIN_API_ACCESS_TOKEN_AUDIENCE: _envAssert.envAssert.isString(),
139
- ADMIN_ACCESS_TOKEN_ISSUER: _envAssert.envAssert.isString()
125
+ ACCESS_TOKEN_ISSUER: _envAssert.envAssert.isString()
140
126
  });
141
127
  let options;
142
128
  switch (issuer) {
@@ -147,13 +133,6 @@ async function jwtVerify(token, issuer = _const.TokenIssuer.AUTH_SERVICE) {
147
133
  algorithms
148
134
  };
149
135
  break;
150
- case _const.TokenIssuer.ADMIN_API:
151
- options = {
152
- audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE],
153
- issuer: [process.env.ADMIN_ACCESS_TOKEN_ISSUER],
154
- algorithms
155
- };
156
- break;
157
136
  default:
158
137
  throw new _EngineError.EngineError({
159
138
  message: `Invalid token issuer specified "${issuer}"`
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.js","names":["_jsonwebtoken","require","_fs","_interopRequireDefault","_const","_EngineError","_KeySet","_WebError","_checkEnvironment","_envAssert","_report","keySet","exports","adminKeySet","namespace","initKeySets","process","env","CHART","ECDSA_PUBLIC_KEY","EngineError","message","KeySet","file","AUTH_SERVICE_URL","internal","promise","init","bind","ADMIN_API_ECDSA_PUBLIC_KEY","pem","push","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","ADMIN_API_ACCESS_TOKEN_AUDIENCE","ADMIN_ACCESS_TOKEN_ISSUER","options","audience","ADMIN_API","resolve","reject","verify","result","undefined","generateJwtToken","user","signOptions","algorithm","expiresIn","keyid","Object","keys","getKeys","privateKey","fs","readFileSync","PRIVATE_KEY_PATH","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 path from 'path';\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;\nexport let adminKeySet: 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 keySet = new KeySet(`./keys/jwks.json`, { internal: true, file: true });\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 // Load the key set for the admin api\n if (!process.env.ADMIN_API_ECDSA_PUBLIC_KEY)\n throw new EngineError({\n message:\n \"Admin API's authentication JWT signing public key is not defined\"\n });\n adminKeySet = new KeySet(process.env.ADMIN_API_ECDSA_PUBLIC_KEY, {\n pem: true\n });\n promise.push(adminKeySet.init.bind(adminKeySet)());\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 if (adminKeySet) adminKeySet.shutdown.bind(adminKeySet)();\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 || !adminKeySet) {\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 ADMIN_API_ACCESS_TOKEN_AUDIENCE: envAssert.isString(),\n ADMIN_ACCESS_TOKEN_ISSUER: 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 case TokenIssuer.ADMIN_API:\n options = {\n audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string],\n issuer: [process.env.ADMIN_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 data: { token },\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: '1h',\n issuer: process.env.ACCESS_TOKEN_ISSUER,\n audience: process.env.ACCESS_TOKEN_AUDIENCE,\n keyid: Object.keys(keySet?.getKeys() ?? {})[0]\n };\n\n const privateKey = fs.readFileSync(\n process.env.PRIVATE_KEY_PATH ?? 'keys/private-key.pem',\n 'utf8'\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","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","options","audience","resolve","reject","verify","result","undefined","generateJwtToken","user","signOptions","algorithm","expiresIn","keyid","Object","keys","getKeys","privateKey","fs","readFileSync","PRIVATE_KEY_PATH","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 keySet = new KeySet(`./keys/jwks.json`, { internal: true, file: true });\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 });\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 data: { token },\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: '1h',\n issuer: process.env.ACCESS_TOKEN_ISSUER,\n audience: process.env.ACCESS_TOKEN_AUDIENCE,\n keyid: Object.keys(keySet?.getKeys() ?? {})[0]\n };\n\n const privateKey = fs.readFileSync(\n process.env.PRIVATE_KEY_PATH ?? 'keys/private-key.pem',\n 'utf8'\n );\n const token = sign({ user }, privateKey, signOptions);\n\n return token;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -15,7 +15,6 @@ var _WebError = require("../../entities/WebError");
15
15
  require("../../middleware/authHmac/authHmac.types");
16
16
  require("../../middleware/authJwt/authJwt.types");
17
17
  require("../../middleware/authTls/authTls.types");
18
- require("../../middleware/authAdmin/authAdmin.types");
19
18
  /** Default generic logger */
20
19
  function reportInfo(data) {
21
20
  return (0, _output.output)({
@@ -57,7 +56,7 @@ function reportError(error, request) {
57
56
  logEntry = {
58
57
  ...logEntry,
59
58
  context: {
60
- user: request.user?.id ?? request.hosts?.join(',') ?? request.admin?.email,
59
+ user: request.user?.id ?? request.hosts?.join(','),
61
60
  httpRequest: {
62
61
  url: request.originalUrl,
63
62
  method: request.method,
@@ -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","admin","email","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';\nimport {} from 'middleware/authAdmin/authAdmin.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:\n request.user?.id ?? request.hosts?.join(',') ?? request.admin?.email,\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: undefined | Array<RegExp>;\n\n/** Generate the namespace selectors based on the debug variable */\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/** Reset the namespace selectors */\nexport function resetNamespaceSelector(): void {\n NAMESPACE_SELECTORS = undefined;\n}\n\nlet debugNamespace: string | undefined;\n\n/** Log a message for debugging purpose, based on a namespace specified in an environment variable */\nexport function reportDebug(data: DebugLogEntry): FullLogEntry | undefined {\n if (!NAMESPACE_SELECTORS) initNamespaceSelector();\n let { namespace } = data;\n const isEngineReport = namespace ? namespace.startsWith('engine') : false;\n\n if (debugNamespace && !isEngineReport) {\n namespace = debugNamespace + ':' + namespace;\n }\n\n const match =\n namespace &&\n NAMESPACE_SELECTORS &&\n NAMESPACE_SELECTORS.some((selector) => selector.test(namespace));\n if (!match) return;\n\n // Generate a prefix with the right most 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/** Specify a global debugging namespace */\nreportDebug.setNameSpace = function (globalNamespace: string): void {\n debugNamespace = globalNamespace;\n};\n\n/** Remove any defined global namespace */\nreportDebug.clearNamespace = function (): void {\n debugNamespace = undefined;\n};\n"],"mappings":"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","ignoreList":[]}
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:\n 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: undefined | Array<RegExp>;\n\n/** Generate the namespace selectors based on the debug variable */\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/** Reset the namespace selectors */\nexport function resetNamespaceSelector(): void {\n NAMESPACE_SELECTORS = undefined;\n}\n\nlet debugNamespace: string | undefined;\n\n/** Log a message for debugging purpose, based on a namespace specified in an environment variable */\nexport function reportDebug(data: DebugLogEntry): FullLogEntry | undefined {\n if (!NAMESPACE_SELECTORS) initNamespaceSelector();\n let { namespace } = data;\n const isEngineReport = namespace ? namespace.startsWith('engine') : false;\n\n if (debugNamespace && !isEngineReport) {\n namespace = debugNamespace + ':' + namespace;\n }\n\n const match =\n namespace &&\n NAMESPACE_SELECTORS &&\n NAMESPACE_SELECTORS.some((selector) => selector.test(namespace));\n if (!match) return;\n\n // Generate a prefix with the right most 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/** Specify a global debugging namespace */\nreportDebug.setNameSpace = function (globalNamespace: string): void {\n debugNamespace = globalNamespace;\n};\n\n/** Remove any defined global namespace */\nreportDebug.clearNamespace = function (): void {\n debugNamespace = undefined;\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": "1.1.6",
3
+ "version": "1.1.8",
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": {
@@ -9,10 +9,11 @@
9
9
  "lint": "eslint ./src",
10
10
  "lint:fix": "eslint ./src --fix",
11
11
  "prepublish": "npm run build",
12
+ "prepublishOnly": "npm run build",
12
13
  "test": "cross-env NODE_ENV=test nyc --reporter=none mocha test/hooks.ts \"src/**/*.test.ts\"",
13
- "coverage": "nyc report --reporter=text",
14
+ "test:file": "cross-env NODE_ENV=test nyc --reporter=none mocha test/hooks.ts",
15
+ "coverage": "nyc report --report-dir=./.test-coverage --reporter=html --reporter=text",
14
16
  "coverage:ci": "nyc report --reporter=text-summary",
15
- "prepublishOnly": "npm run build",
16
17
  "test:ci": "npm run test -- --reporter spec",
17
18
  "test:compose": "docker-compose up --abort-on-container-exit --build"
18
19
  },
@@ -44,7 +45,7 @@
44
45
  "@google/generative-ai": "^0.21.0",
45
46
  "ajv": "^8.17.1",
46
47
  "axios": "^1.7.9",
47
- "backend-test-tools": "^1.0.4",
48
+ "backend-test-tools": "^1.0.6",
48
49
  "body-parser": "^1.20.3",
49
50
  "busboy": "^1.6.0",
50
51
  "callsite": "^1.0.0",
@@ -104,6 +105,7 @@
104
105
  "@types/callsite": "^1.0.34",
105
106
  "@types/chai": "^5.0.1",
106
107
  "@types/chai-as-promised": "^8.0.1",
108
+ "@types/cors": "^2.8.17",
107
109
  "@types/express": "^5.0.0",
108
110
  "@types/filesize-parser": "^1.5.3",
109
111
  "@types/flat": "^5.0.5",
@@ -130,8 +132,8 @@
130
132
  "@typescript-eslint/eslint-plugin": "^8.18.1",
131
133
  "babel-plugin-istanbul": "^7.0.0",
132
134
  "babel-plugin-module-resolver": "^5.0.2",
133
- "chai": "^5.1.2",
134
- "chai-as-promised": "^8.0.1",
135
+ "chai": "^4.5.0",
136
+ "chai-as-promised": "^7.1.2",
135
137
  "cross-env": "^7.0.3",
136
138
  "eslint": "^9.17.0",
137
139
  "factory-waifu": "^1.0.1",
@@ -147,7 +149,7 @@
147
149
  "rimraf": "^6.0.1",
148
150
  "shx": "^0.3.4",
149
151
  "sinon": "^19.0.2",
150
- "sinon-chai": "^4.0.0",
152
+ "sinon-chai": "^3.5.0",
151
153
  "supertest": "^7.0.0",
152
154
  "tmp": "^0.2.3",
153
155
  "ts-node": "^10.9.2",
@@ -1,9 +1,7 @@
1
1
  /** Enum to identify access tokens JWT issuers */
2
2
  export enum TokenIssuer {
3
3
  /** For tokens issued by the auth service */
4
- AUTH_SERVICE,
5
- /** For tokens issued by the admin API */
6
- ADMIN_API
4
+ AUTH_SERVICE
7
5
  }
8
6
 
9
7
  export const TOKEN_ISSUERS = Object.values(TokenIssuer);
@@ -176,95 +176,6 @@ describe('Entity - Endpoint', () => {
176
176
  await server.shutdown();
177
177
  });
178
178
 
179
- // AUTH ADMIN
180
-
181
- it('it should authenticate with authAdmin middleware', async () => {
182
- const email = faker.internet.email();
183
- const permission = faker.lorem.word();
184
- const token = generateAccessToken(
185
- email,
186
- {
187
- audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string],
188
- issuer: process.env.ADMIN_ACCESS_TOKEN_ISSUER as string
189
- },
190
- { per: permission }
191
- );
192
- const endpoint = new Endpoint({
193
- ...config,
194
- authType: EndpointAuthType.ADMIN,
195
- authParams: { permission },
196
- handler: (req: Request, res: Response) => {
197
- res.sendStatus(200);
198
- }
199
- } as EndpointOptions<EndpointAuthType.ADMIN>);
200
-
201
- endpoint.register(app);
202
- await request(app)
203
- .get(PATH)
204
- .set('Authorization', 'Bearer ' + token)
205
- .expect(200);
206
- });
207
-
208
- it('it should authenticate with authAdmin middleware and check permission', async () => {
209
- const email = faker.internet.email();
210
- const permission = faker.lorem.word();
211
- const token = generateAccessToken(
212
- email,
213
- {
214
- audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string],
215
- issuer: process.env.ADMIN_ACCESS_TOKEN_ISSUER as string
216
- },
217
- { per: permission }
218
- );
219
-
220
- const endpoint = new Endpoint({
221
- ...config,
222
- authType: EndpointAuthType.ADMIN,
223
- authParams: { permission },
224
- handler: (req: Request, res: Response) => {
225
- res.sendStatus(200);
226
- }
227
- } as EndpointOptions<EndpointAuthType.ADMIN>);
228
-
229
- endpoint.register(app);
230
- await request(app)
231
- .get(PATH)
232
- .set('Authorization', 'Bearer ' + token)
233
- .expect(200);
234
- });
235
-
236
- it('it should authenticate with authAdmin middleware and check permissions', async () => {
237
- const email = faker.internet.email();
238
- const permissions = [
239
- faker.lorem.word(),
240
- faker.lorem.word(),
241
- faker.lorem.word()
242
- ];
243
- const token = generateAccessToken(
244
- email,
245
- {
246
- audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string],
247
- issuer: process.env.ADMIN_ACCESS_TOKEN_ISSUER as string
248
- },
249
- { per: permissions }
250
- );
251
-
252
- const endpoint = new Endpoint({
253
- ...config,
254
- authType: EndpointAuthType.ADMIN,
255
- authParams: { permission: permissions[1] },
256
- handler: (req: Request, res: Response) => {
257
- res.sendStatus(200);
258
- }
259
- } as EndpointOptions<EndpointAuthType.ADMIN>);
260
-
261
- endpoint.register(app);
262
- await request(app)
263
- .get(PATH)
264
- .set('Authorization', 'Bearer ' + token)
265
- .expect(200);
266
- });
267
-
268
179
  it('it should reject if the user has no valid JWT', async () => {
269
180
  const endpoint = new Endpoint({
270
181
  ...config,
@@ -15,9 +15,7 @@ import {
15
15
  authHmac,
16
16
  authTls,
17
17
  authStatic,
18
- authAdmin,
19
- FileUploaderConfig,
20
- RequestAdminProps
18
+ FileUploaderConfig
21
19
  } from 'middleware';
22
20
 
23
21
  export enum EndpointMethod {
@@ -37,8 +35,7 @@ export enum EndpointAuthType {
37
35
  JWT = 'jwt',
38
36
  TLS = 'tls',
39
37
  HMAC = 'hmac',
40
- STATIC = 'static',
41
- ADMIN = 'admin'
38
+ STATIC = 'static'
42
39
  }
43
40
 
44
41
  export const EndpointAuthTypes = Object.values(EndpointAuthType);
@@ -54,12 +51,6 @@ export type MiddlewareChainElement<T extends EndpointAuthType> =
54
51
  | Middleware<T>
55
52
  | any;
56
53
 
57
- /** Auth related parameters used with Admin authentication */
58
- interface EndpointAuthAdminParams {
59
- /** [Admin] User permission required to use this endpoint */
60
- permission: string;
61
- }
62
-
63
54
  /** Auth related parameters used with HMAC authentication */
64
55
  interface EndpointAuthHmacParams {
65
56
  /** [HMAC] Secret used for signature */
@@ -86,8 +77,6 @@ interface EndpointAuthSpecificParams {
86
77
  [EndpointAuthType.HMAC]: EndpointAuthHmacParams;
87
78
  /** Auth parameters for static authentication */
88
79
  [EndpointAuthType.STATIC]: any;
89
- /** Auth parameters for admin token authentication */
90
- [EndpointAuthType.ADMIN]: EndpointAuthAdminParams;
91
80
  }
92
81
 
93
82
  export type EndpointAuthParams<T extends EndpointAuthType> =
@@ -114,9 +103,7 @@ export const EndpointAuthHandlers = {
114
103
  /** Auth handler for HMAC authentication */
115
104
  [EndpointAuthType.HMAC]: authHmac,
116
105
  /** Auth handler for static authentication */
117
- [EndpointAuthType.STATIC]: authStatic,
118
- /** Auth handler for admin token authentication */
119
- [EndpointAuthType.ADMIN]: authAdmin
106
+ [EndpointAuthType.STATIC]: authStatic
120
107
  };
121
108
 
122
109
  export type EndpointHandler<T extends EndpointAuthType> = (
@@ -172,18 +159,6 @@ export interface TlsRequest<
172
159
  hosts: Array<string>;
173
160
  }
174
161
 
175
- /** Request type when using HMAC authentication */
176
- export interface AdminRequest<
177
- P = ParamsDictionary,
178
- ResBody = any,
179
- ReqBody = any,
180
- ReqQuery = ParsedQs,
181
- Locals extends Record<string, any> = Record<string, any>
182
- > extends Request<P, ResBody, ReqBody, ReqQuery, Locals> {
183
- /** User that identified using a JWT */
184
- admin: RequestAdminProps;
185
- }
186
-
187
162
  /** Mapping of request types in endpoints based on auth type used */
188
163
  export interface EndpointRequestType {
189
164
  /** Request type for no authentication */
@@ -196,8 +171,6 @@ export interface EndpointRequestType {
196
171
  [EndpointAuthType.HMAC]: Request;
197
172
  /** Auth handler for static authentication */
198
173
  [EndpointAuthType.STATIC]: Request;
199
- /** Auth handler for admin token authentication */
200
- [EndpointAuthType.ADMIN]: AdminRequest;
201
174
  }
202
175
 
203
176
  export type SafeMiddleWareChain = Array<
@@ -100,7 +100,7 @@ describe('Entity - KeySet', function () {
100
100
 
101
101
  it('should read a key from a PEM string', async () => {
102
102
  const pem = await readFile(
103
- process.env.ADMIN_API_ECDSA_PUBLIC_KEY as string,
103
+ process.env.ECDSA_PUBLIC_KEY as string,
104
104
  'utf-8'
105
105
  );
106
106
 
@@ -6,6 +6,7 @@ import path from 'path';
6
6
  import { setTimeout as setTimeoutPromise } from 'timers/promises';
7
7
  import { ValidatorSpec } from 'envalid';
8
8
  import express, { Application } from 'express';
9
+ import cors from 'cors';
9
10
  import { Server as WebSocketServer } from 'ws';
10
11
  import { SocketClient } from '../SocketClient';
11
12
  import {
@@ -110,6 +111,14 @@ export class Server {
110
111
 
111
112
  // Create the primary express core that serves the business logic
112
113
  this.app = express();
114
+
115
+ this.app.use(
116
+ cors({
117
+ origin: process.env.CORS_ORIGIN ?? '*',
118
+ methods: 'GET,POST,PUT,DELETE'
119
+ })
120
+ );
121
+
113
122
  this.registerMiddleware(this.app);
114
123
  this.httpServer = createHttpServer(this.app);
115
124
 
@@ -12,6 +12,5 @@ export * from './fileUploader';
12
12
  export * from './metrics';
13
13
  export * from './requestMetrics';
14
14
  export * from './version';
15
- export * from './authAdmin';
16
15
  export * from './geminiFileUploader';
17
16
  export * from './checkPermission';
@@ -19,7 +19,6 @@ export * from './request';
19
19
  export * from './tlsConfig';
20
20
  export * from './tlsRequest';
21
21
  export * from './sendPush';
22
- export * from './getDynamicLink';
23
22
  export * from './sendEmail';
24
23
 
25
24
  // String manipulation
@@ -25,17 +25,4 @@ describe('Utils - JWT', () => {
25
25
  const result = await jwtVerify(token, TokenIssuer.AUTH_SERVICE);
26
26
  expect(result.sub).to.equal(id);
27
27
  });
28
-
29
- it('should pass a token with one correct audience [Admin-API]', async () => {
30
- const id = randomUUID();
31
- const token = generateAccessToken(id, {
32
- audience: [
33
- process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string,
34
- faker.lorem.word()
35
- ],
36
- issuer: process.env.ADMIN_ACCESS_TOKEN_ISSUER
37
- });
38
- const result = await jwtVerify(token, TokenIssuer.ADMIN_API);
39
- expect(result.sub).to.equal(id);
40
- });
41
28
  });
@@ -7,7 +7,6 @@ import {
7
7
  sign
8
8
  } from 'jsonwebtoken';
9
9
  import fs from 'fs';
10
- import path from 'path';
11
10
  import { UserTokenPayload } from './jwt.types';
12
11
  import { TokenIssuer } from 'const';
13
12
  import { EngineError } from 'entities/EngineError';
@@ -18,7 +17,6 @@ import { envAssert } from 'utils/envAssert';
18
17
  import { reportDebug } from 'utils/report';
19
18
 
20
19
  export let keySet: KeySet | undefined;
21
- export let adminKeySet: KeySet | undefined;
22
20
 
23
21
  const namespace = 'engine:utils:jwt';
24
22
 
@@ -50,24 +48,12 @@ export async function initKeySets(): Promise<void> {
50
48
  }
51
49
  const promise = [keySet.init.bind(keySet)()];
52
50
 
53
- // Load the key set for the admin api
54
- if (!process.env.ADMIN_API_ECDSA_PUBLIC_KEY)
55
- throw new EngineError({
56
- message:
57
- "Admin API's authentication JWT signing public key is not defined"
58
- });
59
- adminKeySet = new KeySet(process.env.ADMIN_API_ECDSA_PUBLIC_KEY, {
60
- pem: true
61
- });
62
- promise.push(adminKeySet.init.bind(adminKeySet)());
63
-
64
51
  await Promise.all(promise);
65
52
  }
66
53
 
67
54
  /** Stop fetching keys regularly */
68
55
  export function shutdownKeySets(): void {
69
56
  if (keySet) keySet.shutdown.bind(keySet)();
70
- if (adminKeySet) adminKeySet.shutdown.bind(adminKeySet)();
71
57
  }
72
58
 
73
59
  /** Get the JWT public key */
@@ -78,7 +64,7 @@ function jwtGetKey(header: JwtHeader, callback: SigningKeyCallback): void {
78
64
  return;
79
65
  }
80
66
  // Check that KeySet has been initialized
81
- if (!keySet || !adminKeySet) {
67
+ if (!keySet) {
82
68
  callback(new EngineError({ message: 'KeySet has not been initialized' }));
83
69
  return;
84
70
  }
@@ -139,9 +125,7 @@ export async function jwtVerify(
139
125
  }
140
126
  assertEnvironment({
141
127
  ACCESS_TOKEN_AUDIENCE: envAssert.isString(),
142
- ACCESS_TOKEN_ISSUER: envAssert.isString(),
143
- ADMIN_API_ACCESS_TOKEN_AUDIENCE: envAssert.isString(),
144
- ADMIN_ACCESS_TOKEN_ISSUER: envAssert.isString()
128
+ ACCESS_TOKEN_ISSUER: envAssert.isString()
145
129
  });
146
130
  let options: VerifyOptions | undefined;
147
131
 
@@ -153,13 +137,6 @@ export async function jwtVerify(
153
137
  algorithms
154
138
  };
155
139
  break;
156
- case TokenIssuer.ADMIN_API:
157
- options = {
158
- audience: [process.env.ADMIN_API_ACCESS_TOKEN_AUDIENCE as string],
159
- issuer: [process.env.ADMIN_ACCESS_TOKEN_ISSUER as string],
160
- algorithms
161
- };
162
- break;
163
140
  default:
164
141
  throw new EngineError({
165
142
  message: `Invalid token issuer specified "${issuer as string}"`
@@ -8,7 +8,6 @@ import { WebError } from 'entities/WebError';
8
8
  import {} from 'middleware/authHmac/authHmac.types';
9
9
  import {} from 'middleware/authJwt/authJwt.types';
10
10
  import {} from 'middleware/authTls/authTls.types';
11
- import {} from 'middleware/authAdmin/authAdmin.types';
12
11
 
13
12
  /** Default generic logger */
14
13
  export function reportInfo(data: InfoLogEntry | string): FullLogEntry {
@@ -62,7 +61,7 @@ export function reportError(
62
61
  ...logEntry,
63
62
  context: {
64
63
  user:
65
- request.user?.id ?? request.hosts?.join(',') ?? request.admin?.email,
64
+ request.user?.id ?? request.hosts?.join(','),
66
65
  httpRequest: {
67
66
  url: request.originalUrl,
68
67
  method: request.method,
package/test/env.ts CHANGED
@@ -15,10 +15,7 @@ process.env = {
15
15
  PAYLOAD_SIGNATURE_SECRET: faker.lorem.word(),
16
16
  ACCESS_TOKEN_AUDIENCE: audience,
17
17
  ACCESS_TOKEN_ISSUER: faker.lorem.word(),
18
- ADMIN_API_ACCESS_TOKEN_AUDIENCE: audience,
19
- ADMIN_ACCESS_TOKEN_ISSUER: faker.lorem.word(),
20
18
  AUTH_SERVICE_PUBLIC_URL: faker.internet.url(),
21
- ADMIN_API_PUBLIC_URL: faker.internet.url(),
22
19
  VALID_IPS: '::ffff:127.0.0.1,127.0.0.1,::1',
23
20
  REDIS_HOST: process.env.REDIS_HOST ?? '127.0.0.1',
24
21
  REDIS_PORT: '6379',
@@ -33,9 +30,7 @@ process.env = {
33
30
  TLS_REQUEST_KEY_PASSPHRASE: path.resolve('certs/ecdsa.key.pub'),
34
31
  ECDSA_PRIVATE_KEY: path.resolve('certs/ecdsa.key'),
35
32
  ECDSA_PUBLIC_KEY: path.resolve('certs/ecdsa.key.pub'),
36
- ADMIN_API_ECDSA_PUBLIC_KEY: path.resolve('certs/ecdsa.key.pub'),
37
33
  GITHUB_WEBHOOK_SECRET: faker.lorem.word(),
38
- LINKS_SERVICE_URL: faker.internet.url(),
39
34
  STATIC_TOKEN: faker.lorem.word(),
40
35
  HOSTNAME: faker.lorem.slug(),
41
36
  ELASTIC_SEARCH_HOST:
package/test/hooks.ts CHANGED
@@ -27,8 +27,6 @@ before(async () => {
27
27
 
28
28
  beforeEach(async () => {
29
29
  process.env = { ...savedEnv };
30
- sequelize.init();
31
- sequelize.addModels(modelArray);
32
30
  });
33
31
 
34
32
  afterEach(async () => {
@@ -1,4 +0,0 @@
1
- import { Request, Response, NextFunction } from 'express';
2
- import { EndpointAuthParams, EndpointAuthType } from '../../entities/Endpoint';
3
- /** Generate a middleware to authenticate the client connection with a Admin api */
4
- export declare function authAdmin(options: EndpointAuthParams<EndpointAuthType.ADMIN>): (request: Request, response: Response, next: NextFunction) => Promise<void>;