@discover-cloud/shared 1.2.9 → 1.4.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.
- package/dist/authorization/index.d.ts +2 -2
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/permission-cache.service.d.ts +104 -16
- package/dist/authorization/permission-cache.service.js +177 -148
- package/dist/authorization/permission-checker.d.ts +30 -0
- package/dist/authorization/permission-checker.js +40 -0
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context/request-context.storage.d.ts +21 -0
- package/dist/context/request-context.storage.js +37 -0
- package/dist/contracts/auth-service/account.dto.d.ts +30 -0
- package/dist/contracts/auth-service/account.dto.js +7 -0
- package/dist/contracts/auth-service/auth.dto.d.ts +21 -0
- package/dist/contracts/auth-service/auth.dto.js +10 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/{security → contracts}/index.js +1 -1
- package/dist/contracts/visibility.d.ts +63 -0
- package/dist/contracts/visibility.js +10 -0
- package/dist/dtos/audit-service.types.d.ts +42 -0
- package/dist/dtos/audit-service.types.js +31 -0
- package/dist/dtos/auth-service.dto.d.ts +87 -26
- package/dist/dtos/auth-service.dto.js +4 -0
- package/dist/dtos/cloud-service.dto.d.ts +57 -27
- package/dist/dtos/cloud-service.dto.js +5 -0
- package/dist/dtos/index.d.ts +6 -5
- package/dist/dtos/index.js +1 -0
- package/dist/dtos/insights-service.dto.d.ts +184 -32
- package/dist/dtos/insights-service.dto.js +8 -0
- package/dist/dtos/response.dto.d.ts +12 -83
- package/dist/dtos/response.dto.js +2 -21
- package/dist/dtos/user-service.dto.d.ts +163 -13
- package/dist/enums/domain.enums.d.ts +272 -75
- package/dist/enums/domain.enums.js +329 -102
- package/dist/enums/index.d.ts +2 -2
- package/dist/enums/permissions.enums.d.ts +142 -80
- package/dist/enums/permissions.enums.js +174 -133
- package/dist/errors/app-error.d.ts +13 -18
- package/dist/errors/app-error.js +15 -21
- package/dist/errors/http-errors.d.ts +106 -18
- package/dist/errors/http-errors.js +136 -51
- package/dist/errors/index.d.ts +2 -2
- package/dist/http/index.d.ts +2 -1
- package/dist/http/index.js +1 -0
- package/dist/http/request-context.d.ts +8 -0
- package/dist/http/request-context.js +37 -0
- package/dist/http/service-client.d.ts +93 -40
- package/dist/http/service-client.js +104 -55
- package/dist/index.d.ts +11 -9
- package/dist/index.js +2 -0
- package/dist/jwt/index.d.ts +3 -2
- package/dist/jwt/index.js +2 -1
- package/dist/jwt/machine-jwt-verifier.d.ts +21 -0
- package/dist/jwt/machine-jwt-verifier.js +83 -0
- package/dist/jwt/machine-token-client.d.ts +36 -5
- package/dist/jwt/machine-token-client.js +61 -27
- package/dist/jwt/user-jwt-verifier.d.ts +31 -0
- package/dist/jwt/user-jwt-verifier.js +102 -0
- package/dist/messaging/audit.publisher.d.ts +14 -0
- package/dist/messaging/audit.publisher.js +49 -0
- package/dist/messaging/index.d.ts +2 -0
- package/dist/{dto → messaging}/index.js +2 -3
- package/dist/messaging/rabbitmq.client.d.ts +15 -0
- package/dist/messaging/rabbitmq.client.js +133 -0
- package/dist/middleware/error-handler.middleware.d.ts +8 -28
- package/dist/middleware/error-handler.middleware.js +63 -54
- package/dist/middleware/index.d.ts +10 -8
- package/dist/middleware/index.js +7 -5
- package/dist/middleware/request-context.middleware.d.ts +6 -0
- package/dist/middleware/request-context.middleware.js +48 -0
- package/dist/middleware/require-auth.middleware.d.ts +7 -76
- package/dist/middleware/require-auth.middleware.js +29 -117
- package/dist/middleware/require-machine.middleware.d.ts +13 -0
- package/dist/middleware/require-machine.middleware.js +128 -0
- package/dist/middleware/require-org-permission-from-body.middleware.d.ts +10 -0
- package/dist/middleware/require-org-permission-from-body.middleware.js +23 -0
- package/dist/middleware/require-org-permission.middleware.d.ts +19 -0
- package/dist/middleware/require-org-permission.middleware.js +115 -0
- package/dist/middleware/require-platform-permission.middleware.d.ts +19 -0
- package/dist/middleware/require-platform-permission.middleware.js +91 -0
- package/dist/middleware/require-user.middleware.d.ts +14 -0
- package/dist/middleware/require-user.middleware.js +30 -0
- package/dist/middleware/require-workspace-permission.middleware.d.ts +20 -0
- package/dist/middleware/require-workspace-permission.middleware.js +114 -0
- package/dist/middleware/validate.middleware.d.ts +31 -31
- package/dist/middleware/validate.middleware.js +31 -33
- package/dist/types/audit.types.d.ts +39 -0
- package/dist/types/audit.types.js +30 -0
- package/dist/types/express.types.d.ts +92 -124
- package/dist/types/express.types.js +30 -49
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/date.util.d.ts +6 -0
- package/dist/utils/date.util.js +11 -0
- package/dist/utils/env.util.d.ts +6 -0
- package/dist/utils/env.util.js +19 -0
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +5 -4
- package/dist/utils/logger.util.d.ts +31 -0
- package/dist/utils/logger.util.js +91 -0
- package/dist/utils/pagination.util.d.ts +6 -0
- package/dist/utils/pagination.util.js +20 -0
- package/dist/utils/request-context.als.d.ts +10 -0
- package/dist/utils/request-context.als.js +5 -0
- package/dist/utils/response.util.d.ts +27 -0
- package/dist/utils/response.util.js +56 -0
- package/dist/utils/slug.util.d.ts +9 -0
- package/dist/utils/slug.util.js +32 -0
- package/dist/utils/url-safety.util.d.ts +6 -0
- package/dist/utils/url-safety.util.js +75 -0
- package/package.json +3 -1
- package/dist/authorization/permissions.d.ts +0 -78
- package/dist/authorization/permissions.js +0 -174
- package/dist/context/access-context.d.ts +0 -10
- package/dist/context/access-context.js +0 -2
- package/dist/dto/auth-service.dtos.d.ts +0 -44
- package/dist/dto/auth-service.dtos.js +0 -2
- package/dist/dto/index.d.ts +0 -3
- package/dist/dto/response.dtos.d.ts +0 -55
- package/dist/dto/response.dtos.js +0 -6
- package/dist/dto/user-service.dtos.d.ts +0 -50
- package/dist/dto/user-service.dtos.js +0 -2
- package/dist/enums/auth-service.enums.d.ts +0 -12
- package/dist/enums/auth-service.enums.js +0 -17
- package/dist/enums/permissions.types.d.ts +0 -12
- package/dist/enums/permissions.types.js +0 -17
- package/dist/enums/user-service.enums.d.ts +0 -32
- package/dist/enums/user-service.enums.js +0 -41
- package/dist/internal/index.d.ts +0 -4
- package/dist/internal/index.js +0 -20
- package/dist/internal/internal-jwt.service.d.ts +0 -13
- package/dist/internal/internal-jwt.service.js +0 -88
- package/dist/internal/internal-jwt.types.d.ts +0 -7
- package/dist/internal/internal-jwt.types.js +0 -2
- package/dist/internal/internal-key-manager.d.ts +0 -16
- package/dist/internal/internal-key-manager.js +0 -67
- package/dist/internal/registry.d.ts +0 -8
- package/dist/internal/registry.js +0 -34
- package/dist/internal/service-client.d.ts +0 -9
- package/dist/internal/service-client.js +0 -94
- package/dist/jwt/internal-jwt-verifier.d.ts +0 -41
- package/dist/jwt/internal-jwt-verifier.js +0 -185
- package/dist/jwt/jwt-verifier.d.ts +0 -9
- package/dist/jwt/jwt-verifier.js +0 -36
- package/dist/jwt/service-client.d.ts +0 -7
- package/dist/jwt/service-client.js +0 -87
- package/dist/middleware/authorize.d.ts +0 -3
- package/dist/middleware/authorize.js +0 -24
- package/dist/middleware/authorize.middleware.d.ts +0 -54
- package/dist/middleware/authorize.middleware.js +0 -104
- package/dist/middleware/error-handler.d.ts +0 -4
- package/dist/middleware/error-handler.js +0 -23
- package/dist/middleware/request-id.d.ts +0 -2
- package/dist/middleware/request-id.js +0 -9
- package/dist/middleware/request-id.middleware.d.ts +0 -22
- package/dist/middleware/request-id.middleware.js +0 -34
- package/dist/middleware/require-auth.d.ts +0 -10
- package/dist/middleware/require-auth.js +0 -34
- package/dist/middleware/require-human.middleware.d.ts +0 -2
- package/dist/middleware/require-human.middleware.js +0 -18
- package/dist/middleware/require-internal.middleware.d.ts +0 -18
- package/dist/middleware/require-internal.middleware.js +0 -183
- package/dist/middleware/validate.d.ts +0 -5
- package/dist/middleware/validate.js +0 -18
- package/dist/middleware/validated-merge.middleware.d.ts +0 -20
- package/dist/middleware/validated-merge.middleware.js +0 -33
- package/dist/middleware/verify-internal-jwt.d.ts +0 -7
- package/dist/middleware/verify-internal-jwt.js +0 -25
- package/dist/security/guard.d.ts +0 -10
- package/dist/security/guard.js +0 -40
- package/dist/security/index.d.ts +0 -1
- package/dist/types/express.d.ts +0 -22
- package/dist/types/express.js +0 -3
- package/dist/utils/date.utils.d.ts +0 -25
- package/dist/utils/date.utils.js +0 -30
- package/dist/utils/env.d.ts +0 -46
- package/dist/utils/env.js +0 -61
- package/dist/utils/env.utils.d.ts +0 -46
- package/dist/utils/env.utils.js +0 -61
- package/dist/utils/logger.utils.d.ts +0 -66
- package/dist/utils/logger.utils.js +0 -97
- package/dist/utils/response.d.ts +0 -4
- package/dist/utils/response.js +0 -35
- package/dist/utils/response.utils.d.ts +0 -54
- package/dist/utils/response.utils.js +0 -85
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.InternalJwtVerifier = void 0;
|
|
37
|
-
const jose = __importStar(require("jose"));
|
|
38
|
-
/**
|
|
39
|
-
* INTERNAL JWT VERIFIER (@discover-cloud/shared)
|
|
40
|
-
* ──────────────────────────────────────────────────
|
|
41
|
-
* Verifies the internal JWT minted by the API Gateway, resolves permissions
|
|
42
|
-
* from Redis, and builds the AccessContext attached to req.accessContext.
|
|
43
|
-
*
|
|
44
|
-
* Key source:
|
|
45
|
-
* Remote JWKS — fetched from the Gateway at startup and cached for 10 minutes.
|
|
46
|
-
* Requests made during a JWKS cache miss are blocked until the fetch completes
|
|
47
|
-
* (jose handles this internally with a deduplication lock).
|
|
48
|
-
*
|
|
49
|
-
* Token flow per request:
|
|
50
|
-
* 1. Extract Bearer token from Authorization header (caller's responsibility)
|
|
51
|
-
* 2. Verify JWT signature, iss, aud, exp, nbf, typ → verifyInternal()
|
|
52
|
-
* 3. Guard typ === "internal" (token confusion protection)
|
|
53
|
-
* 4. For human tokens: resolve perms from Redis (derive from role on miss)
|
|
54
|
-
* 5. Build and return AccessContext → buildAccessContext()
|
|
55
|
-
*
|
|
56
|
-
* Token kinds:
|
|
57
|
-
* - Human (isMachine: false) — carries accountId, accountRole, perms
|
|
58
|
-
* - Machine (isMachine: true) — carries serviceId only; no perms
|
|
59
|
-
*
|
|
60
|
-
* Static helpers:
|
|
61
|
-
* InternalJwtVerifier.hasPermission / requirePermission / hasRole / requireRole
|
|
62
|
-
* are pure functions over AccessContext — safe to call anywhere after
|
|
63
|
-
* auth middleware has run and populated req.accessContext.
|
|
64
|
-
*/
|
|
65
|
-
const CLOCK_TOLERANCE_SECONDS = 30;
|
|
66
|
-
const JWKS_CACHE_MAX_AGE_MS = 10 * 60 * 1000; // 10 minutes
|
|
67
|
-
const JWKS_FETCH_TIMEOUT_MS = 5000;
|
|
68
|
-
class InternalJwtVerifier {
|
|
69
|
-
constructor(permissionCache) {
|
|
70
|
-
this.permissionCache = permissionCache;
|
|
71
|
-
const gatewayJwksUri = process.env["GATEWAY_JWKS_URI"] ?? "http://api-gateway:3000/.well-known/jwks.json";
|
|
72
|
-
this.issuer = process.env["INTERNAL_JWT_ISSUER"] ?? "discover-cloud:api-gateway";
|
|
73
|
-
this.audience = process.env["INTERNAL_JWT_AUDIENCE"] ?? "discover-cloud:internal";
|
|
74
|
-
this.jwks = jose.createRemoteJWKSet(new URL(gatewayJwksUri), {
|
|
75
|
-
cacheMaxAge: JWKS_CACHE_MAX_AGE_MS,
|
|
76
|
-
timeoutDuration: JWKS_FETCH_TIMEOUT_MS,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
/* ----------------------------------------------------------------
|
|
80
|
-
verifyInternal
|
|
81
|
-
Full cryptographic verification + typ guard + clock skew tolerance.
|
|
82
|
-
Returns the raw verified payload.
|
|
83
|
-
|
|
84
|
-
Use this directly when you need raw JWT claims (e.g. jti for
|
|
85
|
-
blacklisting). For all other cases, use buildAccessContext() which
|
|
86
|
-
layers permission resolution on top.
|
|
87
|
-
---------------------------------------------------------------- */
|
|
88
|
-
async verifyInternal(token) {
|
|
89
|
-
const { payload } = await jose.jwtVerify(token, this.jwks, {
|
|
90
|
-
issuer: this.issuer,
|
|
91
|
-
audience: this.audience,
|
|
92
|
-
algorithms: ["RS256"],
|
|
93
|
-
clockTolerance: CLOCK_TOLERANCE_SECONDS,
|
|
94
|
-
});
|
|
95
|
-
// Explicit typ guard — rejects external tokens (e.g. user-facing access
|
|
96
|
-
// tokens) that were accidentally forwarded past the gateway. This is a
|
|
97
|
-
// token confusion defence: even if an external token passes signature
|
|
98
|
-
// verification (same key pair), it will be rejected here.
|
|
99
|
-
if (payload.typ !== "internal") {
|
|
100
|
-
throw new jose.errors.JWTClaimValidationFailed(`Token type mismatch: expected "internal", got "${String(payload.typ)}". ` +
|
|
101
|
-
`Ensure clients are not forwarding external tokens past the gateway.`, payload, "typ", "check_failed");
|
|
102
|
-
}
|
|
103
|
-
return payload;
|
|
104
|
-
}
|
|
105
|
-
/* ----------------------------------------------------------------
|
|
106
|
-
buildAccessContext
|
|
107
|
-
Primary method — called by RequireAuthMiddleware on every request.
|
|
108
|
-
Verifies the token, resolves permissions, returns payload + context.
|
|
109
|
-
|
|
110
|
-
Usage in auth middleware:
|
|
111
|
-
const token = extractBearer(req);
|
|
112
|
-
const { payload, context } = await verifier.buildAccessContext(token);
|
|
113
|
-
req.internalAuth = payload;
|
|
114
|
-
req.accessContext = context;
|
|
115
|
-
---------------------------------------------------------------- */
|
|
116
|
-
async buildAccessContext(token) {
|
|
117
|
-
const payload = await this.verifyInternal(token);
|
|
118
|
-
// Machine token — no user context, no permission cache lookup.
|
|
119
|
-
// Machine services are authorised by their serviceId + X-Internal-Secret,
|
|
120
|
-
// not by role-based permissions.
|
|
121
|
-
if (payload.isMachine === true) {
|
|
122
|
-
const machinePayload = payload;
|
|
123
|
-
const context = {
|
|
124
|
-
kind: "machine",
|
|
125
|
-
serviceId: machinePayload.serviceId,
|
|
126
|
-
};
|
|
127
|
-
return { payload, context };
|
|
128
|
-
}
|
|
129
|
-
// Human token — resolve permissions from Redis.
|
|
130
|
-
// On a cache miss, permissions are derived from the static role map
|
|
131
|
-
// (no DB call — the role is already verified in the JWT payload).
|
|
132
|
-
const humanPayload = payload;
|
|
133
|
-
const perms = await this.permissionCache.resolve(humanPayload.accountId, humanPayload.accountRole);
|
|
134
|
-
const context = {
|
|
135
|
-
kind: "human",
|
|
136
|
-
accountId: humanPayload.accountId,
|
|
137
|
-
accountRole: humanPayload.accountRole,
|
|
138
|
-
perms, // always from cache — never read from the JWT directly
|
|
139
|
-
};
|
|
140
|
-
return { payload, context };
|
|
141
|
-
}
|
|
142
|
-
/* ----------------------------------------------------------------
|
|
143
|
-
Static helpers — call on req.accessContext after auth middleware runs.
|
|
144
|
-
These are pure functions; they do not touch Redis or the JWT verifier.
|
|
145
|
-
---------------------------------------------------------------- */
|
|
146
|
-
/**
|
|
147
|
-
* hasPermission
|
|
148
|
-
* Returns true if the context carries the given GlobalPermission.
|
|
149
|
-
* Machine contexts always return false — they carry no user permissions.
|
|
150
|
-
*/
|
|
151
|
-
static hasPermission(ctx, permission) {
|
|
152
|
-
return ctx.kind === "human" && ctx.perms.includes(permission);
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* requirePermission
|
|
156
|
-
* Throws JWTClaimValidationFailed if the permission is absent.
|
|
157
|
-
* Use in middleware for a one-liner gate:
|
|
158
|
-
* InternalJwtVerifier.requirePermission(ctx, GlobalPermission.MANAGE_ACCOUNTS);
|
|
159
|
-
*/
|
|
160
|
-
static requirePermission(ctx, permission) {
|
|
161
|
-
if (!InternalJwtVerifier.hasPermission(ctx, permission)) {
|
|
162
|
-
throw new jose.errors.JWTClaimValidationFailed(`Missing required permission: ${permission}`, {}, "perms", "check_failed");
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* hasRole
|
|
167
|
-
* Returns true if the context carries the given AccountRole.
|
|
168
|
-
* Machine contexts always return false.
|
|
169
|
-
*/
|
|
170
|
-
static hasRole(ctx, role) {
|
|
171
|
-
return ctx.kind === "human" && ctx.accountRole === role;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* requireRole
|
|
175
|
-
* Throws JWTClaimValidationFailed if the role doesn't match.
|
|
176
|
-
* Prefer requirePermission() for most gates — role checks are for the rare
|
|
177
|
-
* cases where a specific role (not just a permission) must be enforced.
|
|
178
|
-
*/
|
|
179
|
-
static requireRole(ctx, role) {
|
|
180
|
-
if (!InternalJwtVerifier.hasRole(ctx, role)) {
|
|
181
|
-
throw new jose.errors.JWTClaimValidationFailed(`Missing required role: ${role}`, {}, "role", "check_failed");
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
exports.InternalJwtVerifier = InternalJwtVerifier;
|
package/dist/jwt/jwt-verifier.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JwtVerifier = void 0;
|
|
4
|
-
const jose_1 = require("jose");
|
|
5
|
-
const errors_1 = require("../errors");
|
|
6
|
-
class JwtVerifier {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.remoteJWKS = null;
|
|
9
|
-
}
|
|
10
|
-
async getJWKS() {
|
|
11
|
-
if (!this.remoteJWKS) {
|
|
12
|
-
const base = process.env.API_GATEWAY_URL;
|
|
13
|
-
this.remoteJWKS = (0, jose_1.createRemoteJWKSet)(new URL(`${base}/.well-known/jwks.json`));
|
|
14
|
-
}
|
|
15
|
-
return this.remoteJWKS;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Verifies the Internal JWT sent by the Gateway.
|
|
19
|
-
*/
|
|
20
|
-
async verifyAccessToken(token) {
|
|
21
|
-
try {
|
|
22
|
-
const JWKS = await this.getJWKS();
|
|
23
|
-
const { payload } = await (0, jose_1.jwtVerify)(token, JWKS, {
|
|
24
|
-
issuer: process.env.INTERNAL_JWT_ISSUER,
|
|
25
|
-
audience: process.env.INTERNAL_JWT_AUDIENCE,
|
|
26
|
-
});
|
|
27
|
-
// Cast to our internal payload which includes the jti
|
|
28
|
-
return payload;
|
|
29
|
-
}
|
|
30
|
-
catch (err) {
|
|
31
|
-
console.error("[JwtVerifier] Internal Token Validation Failed:", err);
|
|
32
|
-
throw new errors_1.UnauthorizedError("Invalid or expired internal token");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
exports.JwtVerifier = JwtVerifier;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.ServiceClient = void 0;
|
|
40
|
-
const axios_1 = __importStar(require("axios"));
|
|
41
|
-
const axios_retry_1 = __importDefault(require("axios-retry"));
|
|
42
|
-
class ServiceClient {
|
|
43
|
-
constructor() {
|
|
44
|
-
this.http = axios_1.default.create({
|
|
45
|
-
timeout: 8000,
|
|
46
|
-
validateStatus: () => true
|
|
47
|
-
});
|
|
48
|
-
this.setupRetry();
|
|
49
|
-
this.setupInterceptors();
|
|
50
|
-
}
|
|
51
|
-
setupRetry() {
|
|
52
|
-
(0, axios_retry_1.default)(this.http, {
|
|
53
|
-
retries: 3,
|
|
54
|
-
retryDelay: axios_retry_1.default.exponentialDelay,
|
|
55
|
-
retryCondition: (err) => {
|
|
56
|
-
if (axios_retry_1.default.isNetworkError(err))
|
|
57
|
-
return true;
|
|
58
|
-
return (err.response?.status ?? 0) >= 500;
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
setupInterceptors() {
|
|
63
|
-
this.http.interceptors.request.use(async (config) => {
|
|
64
|
-
if (!config.headers)
|
|
65
|
-
config.headers = new axios_1.AxiosHeaders();
|
|
66
|
-
// Ensure every request has a tracing ID.
|
|
67
|
-
// If the caller passed one down from the incoming Express request, use it.
|
|
68
|
-
// Otherwise, generate a new one.
|
|
69
|
-
const reqId = config.headers["x-request-id"] ||
|
|
70
|
-
`req_${Math.random().toString(36).slice(2)}`;
|
|
71
|
-
config.headers["x-request-id"] = reqId;
|
|
72
|
-
return config;
|
|
73
|
-
});
|
|
74
|
-
this.http.interceptors.response.use((res) => {
|
|
75
|
-
// Pass through successful responses cleanly
|
|
76
|
-
if (res.status >= 200 && res.status < 300)
|
|
77
|
-
return res;
|
|
78
|
-
// Standardize error throwing for downstream microservice failures
|
|
79
|
-
throw {
|
|
80
|
-
status: res.status,
|
|
81
|
-
message: res.data?.error?.message ?? "Downstream Service Error",
|
|
82
|
-
details: res.data
|
|
83
|
-
};
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
exports.ServiceClient = ServiceClient;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.authorize = void 0;
|
|
4
|
-
const security_1 = require("../security");
|
|
5
|
-
const authorize = (permission) => {
|
|
6
|
-
return (req, res, next) => {
|
|
7
|
-
// 1. Ensure the RequireAuthMiddleware has already run
|
|
8
|
-
if (!req.accessContext) {
|
|
9
|
-
return res.status(401).json({
|
|
10
|
-
success: false,
|
|
11
|
-
error: { message: "Unauthorized: No access context", code: "UNAUTHORIZED" }
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
// 2. Check if the Role in the accessContext has the required Permission
|
|
15
|
-
if (!(0, security_1.isAllowed)(req.accessContext, permission)) {
|
|
16
|
-
return res.status(403).json({
|
|
17
|
-
success: false,
|
|
18
|
-
error: { message: `Forbidden: Missing permission ${permission}`, code: "FORBIDDEN" }
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
next();
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
exports.authorize = authorize;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { GlobalPermission } from "../enums";
|
|
3
|
-
/**
|
|
4
|
-
* AUTHORIZE MIDDLEWARE (@discover-cloud/shared)
|
|
5
|
-
* ───────────────────────────────────────────────
|
|
6
|
-
* Permission-gates a route. Must run AFTER requireAuth middleware, which
|
|
7
|
-
* populates req.accessContext from the verified internal JWT + Redis cache.
|
|
8
|
-
*
|
|
9
|
-
* Uses InternalJwtVerifier.hasPermission — permissions come from the Redis
|
|
10
|
-
* permission cache loaded by RequireAuthMiddleware, never from the JWT itself.
|
|
11
|
-
*
|
|
12
|
-
* All error responses go through the shared failure() util to ensure a
|
|
13
|
-
* consistent ApiErrorResponse shape across every service. The error is
|
|
14
|
-
* returned directly (not passed to next()) because these are deterministic
|
|
15
|
-
* middleware guards — there is nothing to recover from downstream.
|
|
16
|
-
*
|
|
17
|
-
* Usage:
|
|
18
|
-
* router.delete(
|
|
19
|
-
* "/accounts/:id",
|
|
20
|
-
* requireAuth,
|
|
21
|
-
* authorize(GlobalPermission.DELETE_ACCOUNT),
|
|
22
|
-
* controller.delete,
|
|
23
|
-
* );
|
|
24
|
-
*/
|
|
25
|
-
export declare const authorize: (permission: GlobalPermission) => (req: Request, res: Response, next: NextFunction) => void;
|
|
26
|
-
/**
|
|
27
|
-
* authorizeAny
|
|
28
|
-
* Passes if the context has AT LEAST ONE of the provided permissions.
|
|
29
|
-
* Useful for routes accessible by multiple roles (e.g. SUPPORT_VIEW or VIEW_ANY_ACCOUNT).
|
|
30
|
-
*
|
|
31
|
-
* Usage:
|
|
32
|
-
* router.get(
|
|
33
|
-
* "/accounts/:id",
|
|
34
|
-
* requireAuth,
|
|
35
|
-
* authorizeAny(GlobalPermission.VIEW_ANY_ACCOUNT, GlobalPermission.SUPPORT_VIEW),
|
|
36
|
-
* controller.getById,
|
|
37
|
-
* );
|
|
38
|
-
*/
|
|
39
|
-
export declare const authorizeAny: (...permissions: GlobalPermission[]) => (req: Request, res: Response, next: NextFunction) => void;
|
|
40
|
-
/**
|
|
41
|
-
* authorizeAll
|
|
42
|
-
* Passes only if the context has ALL of the provided permissions.
|
|
43
|
-
* Use for routes that require a conjunction of permissions (rare — prefer
|
|
44
|
-
* composing authorize() calls in series if the permissions are independent).
|
|
45
|
-
*
|
|
46
|
-
* Usage:
|
|
47
|
-
* router.post(
|
|
48
|
-
* "/accounts/:id/impersonate",
|
|
49
|
-
* requireAuth,
|
|
50
|
-
* authorizeAll(GlobalPermission.IMPERSONATE_ACCOUNT, GlobalPermission.MANAGE_ACCOUNTS),
|
|
51
|
-
* controller.impersonate,
|
|
52
|
-
* );
|
|
53
|
-
*/
|
|
54
|
-
export declare const authorizeAll: (...permissions: GlobalPermission[]) => (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.authorizeAll = exports.authorizeAny = exports.authorize = void 0;
|
|
4
|
-
const internal_jwt_verifier_1 = require("../jwt/internal-jwt-verifier");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
|
-
/**
|
|
7
|
-
* AUTHORIZE MIDDLEWARE (@discover-cloud/shared)
|
|
8
|
-
* ───────────────────────────────────────────────
|
|
9
|
-
* Permission-gates a route. Must run AFTER requireAuth middleware, which
|
|
10
|
-
* populates req.accessContext from the verified internal JWT + Redis cache.
|
|
11
|
-
*
|
|
12
|
-
* Uses InternalJwtVerifier.hasPermission — permissions come from the Redis
|
|
13
|
-
* permission cache loaded by RequireAuthMiddleware, never from the JWT itself.
|
|
14
|
-
*
|
|
15
|
-
* All error responses go through the shared failure() util to ensure a
|
|
16
|
-
* consistent ApiErrorResponse shape across every service. The error is
|
|
17
|
-
* returned directly (not passed to next()) because these are deterministic
|
|
18
|
-
* middleware guards — there is nothing to recover from downstream.
|
|
19
|
-
*
|
|
20
|
-
* Usage:
|
|
21
|
-
* router.delete(
|
|
22
|
-
* "/accounts/:id",
|
|
23
|
-
* requireAuth,
|
|
24
|
-
* authorize(GlobalPermission.DELETE_ACCOUNT),
|
|
25
|
-
* controller.delete,
|
|
26
|
-
* );
|
|
27
|
-
*/
|
|
28
|
-
const authorize = (permission) => {
|
|
29
|
-
return (req, res, next) => {
|
|
30
|
-
// Ensure RequireAuthMiddleware has already run and populated accessContext.
|
|
31
|
-
// This is a programming error (wrong middleware order), not a client error,
|
|
32
|
-
// but we surface it as 401 so it doesn't silently pass through.
|
|
33
|
-
if (!req.accessContext) {
|
|
34
|
-
(0, utils_1.failure)(res, req, "Unauthorized: No access context", "UNAUTHORIZED", 401);
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
// Check permission against accessContext.perms (populated from Redis cache).
|
|
38
|
-
if (!internal_jwt_verifier_1.InternalJwtVerifier.hasPermission(req.accessContext, permission)) {
|
|
39
|
-
(0, utils_1.failure)(res, req, `Forbidden: Missing permission ${permission}`, "FORBIDDEN", 403);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
next();
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
exports.authorize = authorize;
|
|
46
|
-
/**
|
|
47
|
-
* authorizeAny
|
|
48
|
-
* Passes if the context has AT LEAST ONE of the provided permissions.
|
|
49
|
-
* Useful for routes accessible by multiple roles (e.g. SUPPORT_VIEW or VIEW_ANY_ACCOUNT).
|
|
50
|
-
*
|
|
51
|
-
* Usage:
|
|
52
|
-
* router.get(
|
|
53
|
-
* "/accounts/:id",
|
|
54
|
-
* requireAuth,
|
|
55
|
-
* authorizeAny(GlobalPermission.VIEW_ANY_ACCOUNT, GlobalPermission.SUPPORT_VIEW),
|
|
56
|
-
* controller.getById,
|
|
57
|
-
* );
|
|
58
|
-
*/
|
|
59
|
-
const authorizeAny = (...permissions) => {
|
|
60
|
-
return (req, res, next) => {
|
|
61
|
-
const ctx = req.accessContext;
|
|
62
|
-
if (!ctx) {
|
|
63
|
-
(0, utils_1.failure)(res, req, "Unauthorized: No access context", "UNAUTHORIZED", 401);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const hasAny = permissions.some((p) => internal_jwt_verifier_1.InternalJwtVerifier.hasPermission(ctx, p));
|
|
67
|
-
if (!hasAny) {
|
|
68
|
-
(0, utils_1.failure)(res, req, `Forbidden: Missing one of [${permissions.join(", ")}]`, "FORBIDDEN", 403);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
next();
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
exports.authorizeAny = authorizeAny;
|
|
75
|
-
/**
|
|
76
|
-
* authorizeAll
|
|
77
|
-
* Passes only if the context has ALL of the provided permissions.
|
|
78
|
-
* Use for routes that require a conjunction of permissions (rare — prefer
|
|
79
|
-
* composing authorize() calls in series if the permissions are independent).
|
|
80
|
-
*
|
|
81
|
-
* Usage:
|
|
82
|
-
* router.post(
|
|
83
|
-
* "/accounts/:id/impersonate",
|
|
84
|
-
* requireAuth,
|
|
85
|
-
* authorizeAll(GlobalPermission.IMPERSONATE_ACCOUNT, GlobalPermission.MANAGE_ACCOUNTS),
|
|
86
|
-
* controller.impersonate,
|
|
87
|
-
* );
|
|
88
|
-
*/
|
|
89
|
-
const authorizeAll = (...permissions) => {
|
|
90
|
-
return (req, res, next) => {
|
|
91
|
-
const ctx = req.accessContext;
|
|
92
|
-
if (!ctx) {
|
|
93
|
-
(0, utils_1.failure)(res, req, "Unauthorized: No access context", "UNAUTHORIZED", 401);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const missingPermissions = permissions.filter((p) => !internal_jwt_verifier_1.InternalJwtVerifier.hasPermission(ctx, p));
|
|
97
|
-
if (missingPermissions.length > 0) {
|
|
98
|
-
(0, utils_1.failure)(res, req, `Forbidden: Missing permissions [${missingPermissions.join(", ")}]`, "FORBIDDEN", 403);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
next();
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
exports.authorizeAll = authorizeAll;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GlobalErrorHandler = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
|
-
class GlobalErrorHandler {
|
|
7
|
-
static handle(err, req, res, _next) {
|
|
8
|
-
// Standardized logging using req.id from your requestId middleware
|
|
9
|
-
console.error(`[req ${req.id}]`, err);
|
|
10
|
-
// 1. Zod Validation Errors
|
|
11
|
-
if (err instanceof zod_1.ZodError) {
|
|
12
|
-
return (0, utils_1.failure)(res, "Validation failed", 400, err.flatten());
|
|
13
|
-
}
|
|
14
|
-
// 2. Custom App Errors (instanceof checks for BadRequestError, etc.)
|
|
15
|
-
const custom = err;
|
|
16
|
-
if (custom.statusCode) {
|
|
17
|
-
return (0, utils_1.failure)(res, custom.message ?? "Error", custom.statusCode, custom.details);
|
|
18
|
-
}
|
|
19
|
-
// 3. Fallback: Internal Server Error
|
|
20
|
-
return (0, utils_1.failure)(res, "Internal Server Error", 500);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.GlobalErrorHandler = GlobalErrorHandler;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.requestId = void 0;
|
|
4
|
-
const crypto_1 = require("crypto");
|
|
5
|
-
const requestId = (req, _res, next) => {
|
|
6
|
-
req.id = (0, crypto_1.randomUUID)();
|
|
7
|
-
next();
|
|
8
|
-
};
|
|
9
|
-
exports.requestId = requestId;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
/**
|
|
3
|
-
* REQUEST ID MIDDLEWARE (@discover-cloud/shared)
|
|
4
|
-
* ─────────────────────────────────────────────────
|
|
5
|
-
* Attaches a unique request ID to req.id for distributed tracing.
|
|
6
|
-
* Register early in the middleware stack — before any logger or handler
|
|
7
|
-
* that needs to include the request ID in its output.
|
|
8
|
-
*
|
|
9
|
-
* Priority:
|
|
10
|
-
* 1. x-request-id header forwarded by the API Gateway (or load balancer)
|
|
11
|
-
* 2. Newly generated UUID v4 if no upstream header is present
|
|
12
|
-
*
|
|
13
|
-
* Why forward the upstream header?
|
|
14
|
-
* The gateway mints a requestId and stamps it on every internal request.
|
|
15
|
-
* If downstream services generate their own IDs, the same logical request
|
|
16
|
-
* carries different IDs in each service's logs, breaking cross-service
|
|
17
|
-
* log correlation. Forwarding the upstream ID keeps the trace consistent.
|
|
18
|
-
*
|
|
19
|
-
* The resolved ID is also echoed back on the response via x-request-id
|
|
20
|
-
* so clients and proxies can correlate their own logs with the service's.
|
|
21
|
-
*/
|
|
22
|
-
export declare const requestId: (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.requestId = void 0;
|
|
4
|
-
const crypto_1 = require("crypto");
|
|
5
|
-
/**
|
|
6
|
-
* REQUEST ID MIDDLEWARE (@discover-cloud/shared)
|
|
7
|
-
* ─────────────────────────────────────────────────
|
|
8
|
-
* Attaches a unique request ID to req.id for distributed tracing.
|
|
9
|
-
* Register early in the middleware stack — before any logger or handler
|
|
10
|
-
* that needs to include the request ID in its output.
|
|
11
|
-
*
|
|
12
|
-
* Priority:
|
|
13
|
-
* 1. x-request-id header forwarded by the API Gateway (or load balancer)
|
|
14
|
-
* 2. Newly generated UUID v4 if no upstream header is present
|
|
15
|
-
*
|
|
16
|
-
* Why forward the upstream header?
|
|
17
|
-
* The gateway mints a requestId and stamps it on every internal request.
|
|
18
|
-
* If downstream services generate their own IDs, the same logical request
|
|
19
|
-
* carries different IDs in each service's logs, breaking cross-service
|
|
20
|
-
* log correlation. Forwarding the upstream ID keeps the trace consistent.
|
|
21
|
-
*
|
|
22
|
-
* The resolved ID is also echoed back on the response via x-request-id
|
|
23
|
-
* so clients and proxies can correlate their own logs with the service's.
|
|
24
|
-
*/
|
|
25
|
-
const requestId = (req, res, next) => {
|
|
26
|
-
const upstream = req.headers["x-request-id"];
|
|
27
|
-
// Header can be a string array (multi-value header) — take the first value.
|
|
28
|
-
const id = Array.isArray(upstream) ? upstream[0] : (upstream ?? (0, crypto_1.randomUUID)());
|
|
29
|
-
req.id = id;
|
|
30
|
-
// Echo back on the response for client-side and proxy-side correlation.
|
|
31
|
-
res.setHeader("x-request-id", id);
|
|
32
|
-
next();
|
|
33
|
-
};
|
|
34
|
-
exports.requestId = requestId;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { InternalJwtPayload } from "../types";
|
|
3
|
-
export interface IJwtVerifier {
|
|
4
|
-
verifyAccessToken(token: string): Promise<InternalJwtPayload>;
|
|
5
|
-
}
|
|
6
|
-
export declare class RequireAuthMiddleware {
|
|
7
|
-
private readonly verifier;
|
|
8
|
-
constructor(verifier: IJwtVerifier);
|
|
9
|
-
handle: (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
10
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RequireAuthMiddleware = void 0;
|
|
4
|
-
const errors_1 = require("../errors");
|
|
5
|
-
class RequireAuthMiddleware {
|
|
6
|
-
constructor(verifier) {
|
|
7
|
-
this.verifier = verifier;
|
|
8
|
-
this.handle = async (req, _res, next) => {
|
|
9
|
-
const header = req.headers.authorization;
|
|
10
|
-
if (!header?.startsWith("Bearer ")) {
|
|
11
|
-
return next(new errors_1.UnauthorizedError("Missing Authorization header"));
|
|
12
|
-
}
|
|
13
|
-
const token = header.slice(7);
|
|
14
|
-
try {
|
|
15
|
-
// 1. Verify against Gateway Public Keys
|
|
16
|
-
const payload = await this.verifier.verifyAccessToken(token);
|
|
17
|
-
// 2. Store the raw payload (Access to .jti for logouts/suspensions)
|
|
18
|
-
req.internalAuth = payload;
|
|
19
|
-
// 3. Build AccessContext if it's a human user
|
|
20
|
-
if (payload.accountId && payload.accountRole) {
|
|
21
|
-
req.accessContext = {
|
|
22
|
-
accountId: payload.accountId,
|
|
23
|
-
accountRole: payload.accountRole,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
next();
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
next(new errors_1.UnauthorizedError("Unauthorized: Token validation failed"));
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.RequireAuthMiddleware = RequireAuthMiddleware;
|