node-server-engine 1.11.2 → 1.12.0

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 (26) hide show
  1. package/README.md +78 -0
  2. package/dist/middleware/index.d.ts +1 -0
  3. package/dist/middleware/index.js +11 -0
  4. package/dist/middleware/index.js.map +1 -1
  5. package/dist/middleware/verificationToken/index.d.ts +2 -0
  6. package/dist/middleware/verificationToken/index.js +28 -0
  7. package/dist/middleware/verificationToken/index.js.map +1 -0
  8. package/dist/middleware/verificationToken/verificationToken.d.ts +3 -0
  9. package/dist/middleware/verificationToken/verificationToken.js +96 -0
  10. package/dist/middleware/verificationToken/verificationToken.js.map +1 -0
  11. package/dist/middleware/verificationToken/verificationToken.types.d.ts +31 -0
  12. package/dist/middleware/verificationToken/verificationToken.types.js +6 -0
  13. package/dist/middleware/verificationToken/verificationToken.types.js.map +1 -0
  14. package/dist/utils/index.d.ts +1 -0
  15. package/dist/utils/index.js +11 -0
  16. package/dist/utils/index.js.map +1 -1
  17. package/dist/utils/verificationToken/index.d.ts +2 -0
  18. package/dist/utils/verificationToken/index.js +28 -0
  19. package/dist/utils/verificationToken/index.js.map +1 -0
  20. package/dist/utils/verificationToken/verificationToken.d.ts +4 -0
  21. package/dist/utils/verificationToken/verificationToken.js +192 -0
  22. package/dist/utils/verificationToken/verificationToken.js.map +1 -0
  23. package/dist/utils/verificationToken/verificationToken.types.d.ts +45 -0
  24. package/dist/utils/verificationToken/verificationToken.types.js +2 -0
  25. package/dist/utils/verificationToken/verificationToken.types.js.map +1 -0
  26. package/package.json +1 -1
package/README.md CHANGED
@@ -80,12 +80,14 @@ Framework used to develop Node backend services. This package ships with a lot o
80
80
  - [User Resolver](#user-resolver)
81
81
  - [Gemini File Upload](#gemini-file-upload)
82
82
  - [Check Permission Middleware](#check-permission-middleware)
83
+ - [Verification Token Middleware](#verification-token-middleware)
83
84
  - [Utilities](#utilities)
84
85
  - [Request](#request)
85
86
  - [TLS Request](#tls-request)
86
87
  - [TLS Config](#tls-config)
87
88
  - [Send Push Notification](#send-push-notification)
88
89
  - [Send Email](#send-email)
90
+ - [Verification Token](#verification-token)
89
91
  - [Parameters](#parameters)
90
92
  - [Return Status](#return-status)
91
93
  - [Gemini File Upload](#gemini-file-upload-1)
@@ -1976,6 +1978,42 @@ checkPermission(['admin', 'moderator'])
1976
1978
  };
1977
1979
  ```
1978
1980
 
1981
+ ---
1982
+
1983
+ ### Verification Token Middleware
1984
+
1985
+ ⚠️ **Must be used in combination with AuthType.JWT**
1986
+
1987
+ Generates a short-lived verification flow for sensitive operations (for example: delete account, change email, payout). The middleware verifies a signed verification token and the OTP provided by the user, and binds it to a specific action.
1988
+
1989
+ #### Flow Summary
1990
+
1991
+ 1. Generate a verification token + OTP using the utility (server-side).
1992
+ 2. Send the OTP to the user (SMS/WhatsApp/email).
1993
+ 3. Call the sensitive endpoint with both `x-verification-token` and `x-verification-otp`.
1994
+
1995
+ #### Middleware Usage
1996
+
1997
+ ```javascript
1998
+ import { Endpoint, middleware, AuthType, Method } from 'node-server-engine';
1999
+
2000
+ new Endpoint({
2001
+ path: '/users/:id',
2002
+ method: Method.DELETE,
2003
+ authType: AuthType.JWT,
2004
+ middleware: [middleware.verificationToken('DELETE ACCOUNT', { requireSubject: true })],
2005
+ handler: (req, res) => {
2006
+ res.json({ ok: true });
2007
+ }
2008
+ });
2009
+ ```
2010
+
2011
+ #### Defaults
2012
+
2013
+ - Token header: `x-verification-token`
2014
+ - OTP header: `x-verification-otp`
2015
+ - Body/query fields: `verificationToken`, `verificationOtp`
2016
+
1979
2017
  ## Utilities
1980
2018
 
1981
2019
  The server engine ships with a handful of utility functions that are commonly used by servers
@@ -2104,6 +2142,46 @@ The function returns an object with the following status options:
2104
2142
 
2105
2143
  ---
2106
2144
 
2145
+ ### Verification Token
2146
+
2147
+ Generate and verify a short-lived verification token + OTP for sensitive operations.
2148
+
2149
+ ```javascript
2150
+ import { createVerificationToken, verifyVerificationToken } from 'node-server-engine';
2151
+
2152
+ // Generate token + OTP
2153
+ const { token, otp, expiresAt } = createVerificationToken({
2154
+ action: 'DELETE ACCOUNT',
2155
+ subject: userId,
2156
+ otpLength: 6,
2157
+ expiresInSeconds: 300
2158
+ });
2159
+
2160
+ // Later, verify token + OTP
2161
+ const payload = verifyVerificationToken(token, {
2162
+ action: 'DELETE ACCOUNT',
2163
+ otp,
2164
+ subject: userId
2165
+ });
2166
+ ```
2167
+
2168
+ #### Environment Variables
2169
+
2170
+ - `VERIFICATION_TOKEN_SECRET` (required)
2171
+ - `VERIFICATION_TOKEN_OTP_SECRET` (optional, defaults to `VERIFICATION_TOKEN_SECRET`)
2172
+ - `VERIFICATION_TOKEN_ISSUER` (optional, default: `node-server-engine`)
2173
+ - `VERIFICATION_TOKEN_AUDIENCE` (optional, used when `audience` is not provided)
2174
+
2175
+ #### Multi-service setup
2176
+
2177
+ If you generate verification tokens in one service and verify them in another, **all services must share the same verification secrets** for the same environment:
2178
+
2179
+ - Use the same `VERIFICATION_TOKEN_SECRET` in every service.
2180
+ - If you set `VERIFICATION_TOKEN_OTP_SECRET`, use the same value everywhere.
2181
+ - Keep `VERIFICATION_TOKEN_ISSUER` and `VERIFICATION_TOKEN_AUDIENCE` consistent across services.
2182
+
2183
+ ---
2184
+
2107
2185
  ### Gemini File Upload
2108
2186
 
2109
2187
  Upload a file to Google Gemini AI.
@@ -16,3 +16,4 @@ export * from './version';
16
16
  export * from './geminiFileUploader';
17
17
  export * from './checkPermission';
18
18
  export * from './multiPartFileUploader';
19
+ export * from './verificationToken';
@@ -201,4 +201,15 @@ Object.keys(_multiPartFileUploader).forEach(function (key) {
201
201
  }
202
202
  });
203
203
  });
204
+ var _verificationToken = require("./verificationToken");
205
+ Object.keys(_verificationToken).forEach(function (key) {
206
+ if (key === "default" || key === "__esModule") return;
207
+ if (key in exports && exports[key] === _verificationToken[key]) return;
208
+ Object.defineProperty(exports, key, {
209
+ enumerable: true,
210
+ get: function () {
211
+ return _verificationToken[key];
212
+ }
213
+ });
214
+ });
204
215
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_requestLogger","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './requestLogger';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_error","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_healthCheck","_validate","_fourOhFour","_authJwt","_authHmac","_authStatic","_swaggerDocs","_authTls","_userResolver","_fileUploader","_metrics","_requestMetrics","_requestLogger","_version","_geminiFileUploader","_checkPermission","_multiPartFileUploader","_verificationToken"],"sources":["../../src/middleware/index.ts"],"sourcesContent":["export * from './error';\nexport * from './healthCheck';\nexport * from './validate';\nexport * from './fourOhFour';\nexport * from './authJwt';\nexport * from './authHmac';\nexport * from './authStatic';\nexport * from './swaggerDocs';\nexport * from './authTls';\nexport * from './userResolver';\nexport * from './fileUploader';\nexport * from './metrics';\nexport * from './requestMetrics';\nexport * from './requestLogger';\nexport * from './version';\nexport * from './geminiFileUploader';\nexport * from './checkPermission';\nexport * from './multiPartFileUploader';\nexport * from './verificationToken';"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from './verificationToken';
2
+ export * from './verificationToken.types';
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _verificationToken = require("./verificationToken");
7
+ Object.keys(_verificationToken).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _verificationToken[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _verificationToken[key];
14
+ }
15
+ });
16
+ });
17
+ var _verificationToken2 = require("./verificationToken.types");
18
+ Object.keys(_verificationToken2).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _verificationToken2[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _verificationToken2[key];
25
+ }
26
+ });
27
+ });
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_verificationToken","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_verificationToken2"],"sources":["../../../src/middleware/verificationToken/index.ts"],"sourcesContent":["export * from './verificationToken';\nexport * from './verificationToken.types';\n"],"mappings":";;;;;AAAA,IAAAA,kBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,kBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,kBAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,kBAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,mBAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,mBAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,mBAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,mBAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { VerificationTokenMiddlewareOptions } from './verificationToken.types';
3
+ export declare function verificationToken(action: string, options?: VerificationTokenMiddlewareOptions): (request: Request, response: Response, next: NextFunction) => void;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.verificationToken = verificationToken;
7
+ var _WebError = require("../../entities/WebError");
8
+ var _report = require("../../utils/report");
9
+ var _verificationToken = require("../../utils/verificationToken");
10
+ const namespace = 'engine:middleware:verificationToken';
11
+ const DEFAULT_TOKEN_HEADER = 'x-verification-token';
12
+ const DEFAULT_OTP_HEADER = 'x-verification-otp';
13
+ const DEFAULT_TOKEN_FIELD = 'verificationToken';
14
+ const DEFAULT_OTP_FIELD = 'verificationOtp';
15
+ function readString(request, headerName, fieldName) {
16
+ const headerValue = request.headers[headerName.toLowerCase()];
17
+ if (typeof headerValue === 'string') return headerValue;
18
+ if (Array.isArray(headerValue)) return headerValue[0];
19
+ const bodyValue = request.body && typeof request.body === 'object' ? request.body[fieldName] : undefined;
20
+ if (typeof bodyValue === 'string') return bodyValue;
21
+ const queryValue = request.query && typeof request.query === 'object' ? request.query[fieldName] : undefined;
22
+ if (typeof queryValue === 'string') return queryValue;
23
+ if (Array.isArray(queryValue)) return queryValue[0];
24
+ return undefined;
25
+ }
26
+ function verificationToken(action, options = {}) {
27
+ return (request, _response, next) => {
28
+ const tokenHeader = options.tokenHeader ?? DEFAULT_TOKEN_HEADER;
29
+ const otpHeader = options.otpHeader ?? DEFAULT_OTP_HEADER;
30
+ const tokenField = options.tokenField ?? DEFAULT_TOKEN_FIELD;
31
+ const otpField = options.otpField ?? DEFAULT_OTP_FIELD;
32
+ const requireOtp = options.requireOtp !== false;
33
+ const token = readString(request, tokenHeader, tokenField);
34
+ if (!token) {
35
+ throw new _WebError.WebError({
36
+ errorCode: 'verification_token_missing',
37
+ statusCode: 400,
38
+ message: 'Verification token is required',
39
+ data: {
40
+ tokenHeader,
41
+ tokenField
42
+ }
43
+ });
44
+ }
45
+ const otp = readString(request, otpHeader, otpField);
46
+ if (requireOtp && !otp) {
47
+ throw new _WebError.WebError({
48
+ errorCode: 'verification_otp_missing',
49
+ statusCode: 400,
50
+ message: 'Verification OTP is required',
51
+ data: {
52
+ otpHeader,
53
+ otpField
54
+ }
55
+ });
56
+ }
57
+ const resolvedSubject = options.subjectResolver ? options.subjectResolver(request) : request.user?.id ?? request.user?.sub;
58
+ const payload = (0, _verificationToken.verifyVerificationToken)(token, {
59
+ action,
60
+ otp: requireOtp ? otp : undefined,
61
+ issuer: options.issuer,
62
+ audience: options.audience
63
+ });
64
+ if (resolvedSubject) {
65
+ if (!payload.sub && options.requireSubject) {
66
+ throw new _WebError.WebError({
67
+ errorCode: 'verification_failed',
68
+ statusCode: 403,
69
+ message: 'Verification token missing subject'
70
+ });
71
+ }
72
+ if (payload.sub && payload.sub !== resolvedSubject) {
73
+ throw new _WebError.WebError({
74
+ errorCode: 'verification_failed',
75
+ statusCode: 403,
76
+ message: 'Verification subject mismatch',
77
+ data: {
78
+ expected: resolvedSubject,
79
+ actual: payload.sub
80
+ }
81
+ });
82
+ }
83
+ }
84
+ request.verification = payload;
85
+ (0, _report.reportDebug)({
86
+ namespace,
87
+ message: 'Verification token validated',
88
+ data: {
89
+ action: payload.act,
90
+ subject: payload.sub
91
+ }
92
+ });
93
+ next();
94
+ };
95
+ }
96
+ //# sourceMappingURL=verificationToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verificationToken.js","names":["_WebError","require","_report","_verificationToken","namespace","DEFAULT_TOKEN_HEADER","DEFAULT_OTP_HEADER","DEFAULT_TOKEN_FIELD","DEFAULT_OTP_FIELD","readString","request","headerName","fieldName","headerValue","headers","toLowerCase","Array","isArray","bodyValue","body","undefined","queryValue","query","verificationToken","action","options","_response","next","tokenHeader","otpHeader","tokenField","otpField","requireOtp","token","WebError","errorCode","statusCode","message","data","otp","resolvedSubject","subjectResolver","user","id","sub","payload","verifyVerificationToken","issuer","audience","requireSubject","expected","actual","verification","reportDebug","act","subject"],"sources":["../../../src/middleware/verificationToken/verificationToken.ts"],"sourcesContent":["import { Request, Response, NextFunction } from 'express';\nimport { WebError } from 'entities/WebError';\nimport { reportDebug } from 'utils/report';\nimport { verifyVerificationToken } from 'utils/verificationToken';\nimport { VerificationTokenMiddlewareOptions } from './verificationToken.types';\n\nconst namespace = 'engine:middleware:verificationToken';\n\nconst DEFAULT_TOKEN_HEADER = 'x-verification-token';\nconst DEFAULT_OTP_HEADER = 'x-verification-otp';\nconst DEFAULT_TOKEN_FIELD = 'verificationToken';\nconst DEFAULT_OTP_FIELD = 'verificationOtp';\n\nfunction readString(\n request: Request,\n headerName: string,\n fieldName: string\n): string | undefined {\n const headerValue = request.headers[headerName.toLowerCase()];\n if (typeof headerValue === 'string') return headerValue;\n if (Array.isArray(headerValue)) return headerValue[0];\n\n const bodyValue =\n request.body && typeof request.body === 'object'\n ? (request.body as Record<string, unknown>)[fieldName]\n : undefined;\n if (typeof bodyValue === 'string') return bodyValue;\n\n const queryValue =\n request.query && typeof request.query === 'object'\n ? (request.query as Record<string, unknown>)[fieldName]\n : undefined;\n if (typeof queryValue === 'string') return queryValue;\n if (Array.isArray(queryValue)) return queryValue[0];\n\n return undefined;\n}\n\nexport function verificationToken(\n action: string,\n options: VerificationTokenMiddlewareOptions = {}\n): (request: Request, response: Response, next: NextFunction) => void {\n return (request: Request, _response: Response, next: NextFunction): void => {\n const tokenHeader = options.tokenHeader ?? DEFAULT_TOKEN_HEADER;\n const otpHeader = options.otpHeader ?? DEFAULT_OTP_HEADER;\n const tokenField = options.tokenField ?? DEFAULT_TOKEN_FIELD;\n const otpField = options.otpField ?? DEFAULT_OTP_FIELD;\n const requireOtp = options.requireOtp !== false;\n\n const token = readString(request, tokenHeader, tokenField);\n if (!token) {\n throw new WebError({\n errorCode: 'verification_token_missing',\n statusCode: 400,\n message: 'Verification token is required',\n data: { tokenHeader, tokenField }\n });\n }\n\n const otp = readString(request, otpHeader, otpField);\n if (requireOtp && !otp) {\n throw new WebError({\n errorCode: 'verification_otp_missing',\n statusCode: 400,\n message: 'Verification OTP is required',\n data: { otpHeader, otpField }\n });\n }\n\n const resolvedSubject = options.subjectResolver\n ? options.subjectResolver(request)\n : (request.user?.id as string | undefined) ??\n (request.user?.sub as string | undefined);\n\n const payload = verifyVerificationToken(token, {\n action,\n otp: requireOtp ? otp : undefined,\n issuer: options.issuer,\n audience: options.audience\n });\n\n if (resolvedSubject) {\n if (!payload.sub && options.requireSubject) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification token missing subject'\n });\n }\n if (payload.sub && payload.sub !== resolvedSubject) {\n throw new WebError({\n errorCode: 'verification_failed',\n statusCode: 403,\n message: 'Verification subject mismatch',\n data: { expected: resolvedSubject, actual: payload.sub }\n });\n }\n }\n\n request.verification = payload;\n reportDebug({\n namespace,\n message: 'Verification token validated',\n data: { action: payload.act, subject: payload.sub }\n });\n\n next();\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,31 @@
1
+ import type { Request } from 'express';
2
+ import type { VerificationTokenPayload } from '../../utils/verificationToken';
3
+ export interface VerificationTokenMiddlewareOptions {
4
+ /** Header name to read verification token from */
5
+ tokenHeader?: string;
6
+ /** Header name to read OTP from */
7
+ otpHeader?: string;
8
+ /** Body or query field name to read token from */
9
+ tokenField?: string;
10
+ /** Body or query field name to read OTP from */
11
+ otpField?: string;
12
+ /** Resolve subject to verify against token sub */
13
+ subjectResolver?: (request: Request) => string | undefined;
14
+ /** Require OTP for verification */
15
+ requireOtp?: boolean;
16
+ /** Override token issuer */
17
+ issuer?: string;
18
+ /** Optional audience */
19
+ audience?: string | string[];
20
+ /** Enforce that token contains a subject when subjectResolver returns one */
21
+ requireSubject?: boolean;
22
+ }
23
+ export {};
24
+ declare global {
25
+ namespace Express {
26
+ /** Express request object */
27
+ interface Request {
28
+ verification?: VerificationTokenPayload;
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=verificationToken.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verificationToken.types.js","names":[],"sources":["../../../src/middleware/verificationToken/verificationToken.types.ts"],"sourcesContent":["import type { Request } from 'express';\nimport type { VerificationTokenPayload } from 'utils/verificationToken';\n\nexport interface VerificationTokenMiddlewareOptions {\n /** Header name to read verification token from */\n tokenHeader?: string;\n /** Header name to read OTP from */\n otpHeader?: string;\n /** Body or query field name to read token from */\n tokenField?: string;\n /** Body or query field name to read OTP from */\n otpField?: string;\n /** Resolve subject to verify against token sub */\n subjectResolver?: (request: Request) => string | undefined;\n /** Require OTP for verification */\n requireOtp?: boolean;\n /** Override token issuer */\n issuer?: string;\n /** Optional audience */\n audience?: string | string[];\n /** Enforce that token contains a subject when subjectResolver returns one */\n requireSubject?: boolean;\n}\n\nexport {};\n\n// Override the Express request object to add the verification payload\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n /** Express request object */\n interface Request {\n verification?: VerificationTokenPayload;\n }\n }\n}\n"],"mappings":"","ignoreList":[]}
@@ -7,6 +7,7 @@ export * from './envAssert';
7
7
  export * from './createSortedObject';
8
8
  export * from './jwt';
9
9
  export * from './hmac';
10
+ export * from './verificationToken';
10
11
  export * from './createHttpServer';
11
12
  export * from './request';
12
13
  export * from './tlsConfig';
@@ -102,6 +102,17 @@ Object.keys(_hmac).forEach(function (key) {
102
102
  }
103
103
  });
104
104
  });
105
+ var _verificationToken = require("./verificationToken");
106
+ Object.keys(_verificationToken).forEach(function (key) {
107
+ if (key === "default" || key === "__esModule") return;
108
+ if (key in exports && exports[key] === _verificationToken[key]) return;
109
+ Object.defineProperty(exports, key, {
110
+ enumerable: true,
111
+ get: function () {
112
+ return _verificationToken[key];
113
+ }
114
+ });
115
+ });
105
116
  var _createHttpServer = require("./createHttpServer");
106
117
  Object.keys(_createHttpServer).forEach(function (key) {
107
118
  if (key === "default" || key === "__esModule") return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_report","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_filter","_semverCompare","_dbMigration","_checkEnvironment","_envAssert","_createSortedObject","_jwt","_hmac","_createHttpServer","_request","_tlsConfig","_sendPush","_sendEmail","_trimPathSlash","_geminiFileUpload"],"sources":["../../src/utils/index.ts"],"sourcesContent":["// general\nexport * from './report';\nexport * from './filter';\nexport * from './semverCompare';\nexport * from './dbMigration';\n\n// env\nexport * from './checkEnvironment';\nexport * from './envAssert';\n\n// auth\nexport * from './createSortedObject';\nexport * from './jwt';\nexport * from './hmac';\n\n// Networking\nexport * from './createHttpServer';\nexport * from './request';\nexport * from './tlsConfig';\nexport * from './sendPush';\nexport * from './sendEmail';\n\n// String manipulation\nexport * from './trimPathSlash';\n\n// File Upload\nexport * from './geminiFileUpload';\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_report","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_filter","_semverCompare","_dbMigration","_checkEnvironment","_envAssert","_createSortedObject","_jwt","_hmac","_verificationToken","_createHttpServer","_request","_tlsConfig","_sendPush","_sendEmail","_trimPathSlash","_geminiFileUpload"],"sources":["../../src/utils/index.ts"],"sourcesContent":["// general\nexport * from './report';\nexport * from './filter';\nexport * from './semverCompare';\nexport * from './dbMigration';\n\n// env\nexport * from './checkEnvironment';\nexport * from './envAssert';\n\n// auth\nexport * from './createSortedObject';\nexport * from './jwt';\nexport * from './hmac';\nexport * from './verificationToken';\n\n// Networking\nexport * from './createHttpServer';\nexport * from './request';\nexport * from './tlsConfig';\nexport * from './sendPush';\nexport * from './sendEmail';\n\n// String manipulation\nexport * from './trimPathSlash';\n\n// File Upload\nexport * from './geminiFileUpload';\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export * from './verificationToken';
2
+ export * from './verificationToken.types';
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _verificationToken = require("./verificationToken");
7
+ Object.keys(_verificationToken).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _verificationToken[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _verificationToken[key];
14
+ }
15
+ });
16
+ });
17
+ var _verificationToken2 = require("./verificationToken.types");
18
+ Object.keys(_verificationToken2).forEach(function (key) {
19
+ if (key === "default" || key === "__esModule") return;
20
+ if (key in exports && exports[key] === _verificationToken2[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _verificationToken2[key];
25
+ }
26
+ });
27
+ });
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_verificationToken","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_verificationToken2"],"sources":["../../../src/utils/verificationToken/index.ts"],"sourcesContent":["export * from './verificationToken';\nexport * from './verificationToken.types';\n"],"mappings":";;;;;AAAA,IAAAA,kBAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,kBAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,kBAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,kBAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,mBAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,mBAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,mBAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,mBAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ import { VerificationTokenPayload, VerificationTokenOptions, VerificationTokenResult, VerifyVerificationTokenOptions } from './verificationToken.types';
2
+ export declare function createVerificationToken(options: VerificationTokenOptions): VerificationTokenResult;
3
+ export declare const verificationToken: typeof createVerificationToken;
4
+ export declare function verifyVerificationToken(token: string, options?: VerifyVerificationTokenOptions): VerificationTokenPayload;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createVerificationToken = createVerificationToken;
7
+ exports.verificationToken = void 0;
8
+ exports.verifyVerificationToken = verifyVerificationToken;
9
+ var _crypto = require("crypto");
10
+ var _jsonwebtoken = require("jsonwebtoken");
11
+ var _EngineError = require("../../entities/EngineError");
12
+ var _WebError = require("../../entities/WebError");
13
+ var _checkEnvironment = require("../checkEnvironment");
14
+ var _envAssert = require("../envAssert");
15
+ const DEFAULT_OTP_LENGTH = 6;
16
+ const DEFAULT_EXPIRES_IN_SECONDS = 5 * 60;
17
+ const DEFAULT_ISSUER = 'node-server-engine';
18
+ function normalizeAction(action) {
19
+ if (!action || typeof action !== 'string') {
20
+ throw new _EngineError.EngineError({
21
+ message: 'Verification token action must be a non-empty string',
22
+ data: {
23
+ action
24
+ }
25
+ });
26
+ }
27
+ return action.trim().toUpperCase();
28
+ }
29
+ function resolveOtpLength(length) {
30
+ if (length === undefined) return DEFAULT_OTP_LENGTH;
31
+ if (!Number.isInteger(length) || length < 4 || length > 10) {
32
+ throw new _EngineError.EngineError({
33
+ message: 'OTP length must be an integer between 4 and 10',
34
+ data: {
35
+ length
36
+ }
37
+ });
38
+ }
39
+ return length;
40
+ }
41
+ function resolveExpiresInSeconds(expiresInSeconds) {
42
+ if (expiresInSeconds === undefined) return DEFAULT_EXPIRES_IN_SECONDS;
43
+ if (!Number.isInteger(expiresInSeconds) || expiresInSeconds < 30) {
44
+ throw new _EngineError.EngineError({
45
+ message: 'Verification token expiration must be at least 30 seconds',
46
+ data: {
47
+ expiresInSeconds
48
+ }
49
+ });
50
+ }
51
+ return expiresInSeconds;
52
+ }
53
+ function getTokenSecret() {
54
+ const secret = process.env.VERIFICATION_TOKEN_SECRET;
55
+ if (!secret) {
56
+ (0, _checkEnvironment.assertEnvironment)({
57
+ VERIFICATION_TOKEN_SECRET: _envAssert.envAssert.isString()
58
+ });
59
+ }
60
+ return secret;
61
+ }
62
+ function getOtpSecret() {
63
+ return process.env.VERIFICATION_TOKEN_OTP_SECRET ?? getTokenSecret();
64
+ }
65
+ function hashOtp(otp, secret) {
66
+ return (0, _crypto.createHmac)('sha256', secret).update(otp).digest('hex');
67
+ }
68
+ function generateOtp(length) {
69
+ let otp = '';
70
+ for (let index = 0; index < length; index += 1) {
71
+ otp += (0, _crypto.randomInt)(0, 10).toString();
72
+ }
73
+ return otp;
74
+ }
75
+ function buildIssuer(issuer) {
76
+ return issuer ?? process.env.VERIFICATION_TOKEN_ISSUER ?? DEFAULT_ISSUER;
77
+ }
78
+ function buildSignOptions(options) {
79
+ const signOptions = {
80
+ algorithm: 'HS256',
81
+ expiresIn: resolveExpiresInSeconds(options.expiresInSeconds),
82
+ issuer: buildIssuer(options.issuer)
83
+ };
84
+ if (options.audience) {
85
+ signOptions.audience = options.audience;
86
+ } else if (process.env.VERIFICATION_TOKEN_AUDIENCE) {
87
+ signOptions.audience = process.env.VERIFICATION_TOKEN_AUDIENCE;
88
+ }
89
+ return signOptions;
90
+ }
91
+ function normalizeAudience(audience) {
92
+ if (!audience) return undefined;
93
+ if (Array.isArray(audience)) {
94
+ if (audience.length === 0) return undefined;
95
+ return [audience[0], ...audience.slice(1)];
96
+ }
97
+ return audience;
98
+ }
99
+ function buildVerifyOptions(options) {
100
+ const verifyOptions = {
101
+ algorithms: ['HS256'],
102
+ issuer: buildIssuer(options.issuer)
103
+ };
104
+ const normalizedAudience = normalizeAudience(options.audience ?? process.env.VERIFICATION_TOKEN_AUDIENCE);
105
+ if (normalizedAudience) verifyOptions.audience = normalizedAudience;
106
+ return verifyOptions;
107
+ }
108
+ function createVerificationToken(options) {
109
+ const action = normalizeAction(options.action);
110
+ const otpLength = resolveOtpLength(options.otpLength);
111
+ const tokenSecret = getTokenSecret();
112
+ const otpSecret = getOtpSecret();
113
+ const otp = generateOtp(otpLength);
114
+ const signOptions = buildSignOptions(options);
115
+ const payload = {
116
+ act: action,
117
+ otp: hashOtp(otp, otpSecret),
118
+ jti: (0, _crypto.randomUUID)(),
119
+ sub: options.subject
120
+ };
121
+ const token = (0, _jsonwebtoken.sign)(payload, tokenSecret, signOptions);
122
+ const expiresInSeconds = signOptions.expiresIn;
123
+ return {
124
+ token,
125
+ otp,
126
+ expiresAt: Date.now() + expiresInSeconds * 1000,
127
+ action
128
+ };
129
+ }
130
+ const verificationToken = exports.verificationToken = createVerificationToken;
131
+ function verifyVerificationToken(token, options = {}) {
132
+ const tokenSecret = getTokenSecret();
133
+ let payload;
134
+ try {
135
+ payload = (0, _jsonwebtoken.verify)(token, tokenSecret, buildVerifyOptions(options));
136
+ } catch (error) {
137
+ throw new _WebError.WebError({
138
+ errorCode: 'unauthorized',
139
+ statusCode: 401,
140
+ message: 'Invalid verification token supplied',
141
+ data: {
142
+ token
143
+ },
144
+ error: error instanceof Error ? error : undefined
145
+ });
146
+ }
147
+ if (!payload?.act || !payload?.otp || !payload?.jti) {
148
+ throw new _WebError.WebError({
149
+ errorCode: 'unauthorized',
150
+ statusCode: 401,
151
+ message: 'Malformed verification token payload'
152
+ });
153
+ }
154
+ if (options.action) {
155
+ const action = normalizeAction(options.action);
156
+ if (payload.act !== action) {
157
+ throw new _WebError.WebError({
158
+ errorCode: 'verification_failed',
159
+ statusCode: 403,
160
+ message: 'Verification action mismatch',
161
+ data: {
162
+ expected: action,
163
+ actual: payload.act
164
+ }
165
+ });
166
+ }
167
+ }
168
+ if (options.subject && payload.sub !== options.subject) {
169
+ throw new _WebError.WebError({
170
+ errorCode: 'verification_failed',
171
+ statusCode: 403,
172
+ message: 'Verification subject mismatch',
173
+ data: {
174
+ expected: options.subject,
175
+ actual: payload.sub
176
+ }
177
+ });
178
+ }
179
+ if (options.otp) {
180
+ const otpSecret = getOtpSecret();
181
+ const expectedHash = hashOtp(options.otp, otpSecret);
182
+ if (payload.otp !== expectedHash) {
183
+ throw new _WebError.WebError({
184
+ errorCode: 'verification_failed',
185
+ statusCode: 403,
186
+ message: 'Verification OTP mismatch'
187
+ });
188
+ }
189
+ }
190
+ return payload;
191
+ }
192
+ //# sourceMappingURL=verificationToken.js.map
@@ -0,0 +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","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","verify","error","WebError","errorCode","statusCode","Error","expected","actual","expectedHash"],"sources":["../../../src/utils/verificationToken/verificationToken.ts"],"sourcesContent":["import { randomInt, randomUUID, createHmac } 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\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 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 data: { token },\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 (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":[]}
@@ -0,0 +1,45 @@
1
+ export interface VerificationTokenPayload {
2
+ /** Action this verification token is bound to */
3
+ act: string;
4
+ /** Hashed OTP */
5
+ otp: string;
6
+ /** Unique token id */
7
+ jti: string;
8
+ /** Subject (user or entity id) */
9
+ sub?: string;
10
+ /** Issuer */
11
+ iss?: string;
12
+ /** Audience */
13
+ aud?: string | string[];
14
+ /** Issued at */
15
+ iat?: number;
16
+ /** Expiration */
17
+ exp?: number;
18
+ }
19
+ export interface VerificationTokenOptions {
20
+ /** Action to authorize (ex: "DELETE ACCOUNT") */
21
+ action: string;
22
+ /** Subject (user or entity id) */
23
+ subject?: string;
24
+ /** OTP length, defaults to 6 */
25
+ otpLength?: number;
26
+ /** Token lifetime in seconds, defaults to 300 */
27
+ expiresInSeconds?: number;
28
+ /** Override token issuer */
29
+ issuer?: string;
30
+ /** Optional audience */
31
+ audience?: string | string[];
32
+ }
33
+ export interface VerificationTokenResult {
34
+ token: string;
35
+ otp: string;
36
+ expiresAt: number;
37
+ action: string;
38
+ }
39
+ export interface VerifyVerificationTokenOptions {
40
+ action?: string;
41
+ subject?: string;
42
+ otp?: string;
43
+ issuer?: string;
44
+ audience?: string | string[];
45
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=verificationToken.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verificationToken.types.js","names":[],"sources":["../../../src/utils/verificationToken/verificationToken.types.ts"],"sourcesContent":["export interface VerificationTokenPayload {\n /** Action this verification token is bound to */\n act: string;\n /** Hashed OTP */\n otp: string;\n /** Unique token id */\n jti: string;\n /** Subject (user or entity id) */\n sub?: string;\n /** Issuer */\n iss?: string;\n /** Audience */\n aud?: string | string[];\n /** Issued at */\n iat?: number;\n /** Expiration */\n exp?: number;\n}\n\nexport interface VerificationTokenOptions {\n /** Action to authorize (ex: \"DELETE ACCOUNT\") */\n action: string;\n /** Subject (user or entity id) */\n subject?: string;\n /** OTP length, defaults to 6 */\n otpLength?: number;\n /** Token lifetime in seconds, defaults to 300 */\n expiresInSeconds?: number;\n /** Override token issuer */\n issuer?: string;\n /** Optional audience */\n audience?: string | string[];\n}\n\nexport interface VerificationTokenResult {\n token: string;\n otp: string;\n expiresAt: number;\n action: string;\n}\n\nexport interface VerifyVerificationTokenOptions {\n action?: string;\n subject?: string;\n otp?: string;\n issuer?: string;\n audience?: string | string[];\n}\n"],"mappings":"","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-server-engine",
3
- "version": "1.11.2",
3
+ "version": "1.12.0",
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": {