@terreno/api 0.18.0 → 0.20.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/CHANGELOG.md +25 -0
- package/dist/api.test.js +18 -8
- package/dist/auth.d.ts +5 -5
- package/dist/auth.js +123 -131
- package/dist/configuration.test.js +289 -10
- package/dist/configurationApp.d.ts +72 -5
- package/dist/configurationApp.js +168 -48
- package/dist/configurationPlugin.d.ts +64 -7
- package/dist/configurationPlugin.js +161 -39
- package/dist/configurationPlugin.test.js +238 -1
- package/dist/expressServer.test.js +0 -1
- package/dist/openApi.d.ts +6 -6
- package/dist/openApi.js +21 -21
- package/dist/populate.test.js +23 -0
- package/dist/realtime/queryMatcher.js +0 -6
- package/dist/realtime/queryStore.js +3 -11
- package/dist/realtime/realtime.test.js +41 -34
- package/dist/secretProviders.d.ts +79 -2
- package/dist/secretProviders.js +177 -9
- package/dist/secretProviders.test.d.ts +1 -0
- package/dist/secretProviders.test.js +391 -0
- package/package.json +1 -1
- package/src/actions.openApi.test.ts +1 -1
- package/src/actions.ts +0 -1
- package/src/api.test.ts +10 -2
- package/src/auth.ts +19 -19
- package/src/configuration.test.ts +171 -7
- package/src/configurationApp.ts +213 -30
- package/src/configurationPlugin.test.ts +174 -2
- package/src/configurationPlugin.ts +157 -28
- package/src/expressServer.test.ts +0 -1
- package/src/openApi.ts +21 -21
- package/src/populate.test.ts +25 -0
- package/src/realtime/queryMatcher.ts +0 -6
- package/src/realtime/queryStore.ts +1 -10
- package/src/realtime/realtime.test.ts +24 -24
- package/src/realtime/realtimeApp.ts +0 -1
- package/src/realtime/registry.ts +0 -1
- package/src/realtime/types.ts +0 -4
- package/src/secretProviders.test.ts +186 -0
- package/src/secretProviders.ts +145 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.20.0
|
|
4
|
+
|
|
5
|
+
### Changed (breaking)
|
|
6
|
+
|
|
7
|
+
- **`ConfigurationApp` `POST {basePath}/list-secrets` no longer persists secret values.** Previously it resolved secrets from the provider and wrote the resolved plaintext values into the configuration document. It is now a **read-only validation/status** endpoint: it reports, per secret field, only non-sensitive metadata (`path`, `secretName`, `version`, and a boolean `resolvable`/`isConfigured`) and never writes to the document or returns secret values. A `POST {basePath}/validate-secrets` alias with the same behavior is also registered.
|
|
8
|
+
- **`ConfigurationApp` `PATCH {basePath}` strips `secret: true` fields** from the incoming body, so a secret value can never be written through the update path. Secret fields are read-only via this surface.
|
|
9
|
+
- **`configurationPlugin` no longer adds the `_singleton` unique index by default.** It is now opt-in via `enforceSingletonIndex: true` so it does not double-enforce or conflict with consumers that already guarantee a single non-deleted document via the pre-save guard or their own soft-delete plugin/indexes.
|
|
10
|
+
- **`configurationPlugin` singleton semantics are now soft-delete aware.** `getConfig`, `updateConfig`, and the pre-save guard operate on `{deleted: false}` when the schema has a `deleted` path (e.g. via `isDeletedPlugin`). A soft-deleted document no longer blocks creating a new singleton; hard deletes (`deleteOne`/`deleteMany`/`findOneAndDelete`) remain blocked.
|
|
11
|
+
- **`configurationPlugin.updateConfig` now applies updates via `findOneAndUpdate({$set})` with dotted paths** instead of `Object.assign` + `doc.save()`. This preserves sibling fields inside nested subdocuments on partial patches and tolerates legacy/out-of-schema fields already persisted under `strict: "throw"`.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`SecretProvider.getSecret(secretName, version?)`** — optional `version` parameter. `GcpSecretProvider` resolves `projects/{projectId}/secrets/{name}/versions/{version}` (default `latest`, full resource paths still honored); `EnvSecretProvider` ignores it. Secret fields can declare a `secretVersion` schema option, surfaced on `SecretFieldMeta.version` and passed through `resolveSecrets`.
|
|
16
|
+
- **`CompositeSecretProvider`** — composes an ordered list of providers and returns the first non-null result; a failing provider is warn-logged (secret name only) and resolution falls through to the next.
|
|
17
|
+
- **`CachingSecretProvider`** — wraps any provider with an in-memory TTL cache keyed by `secretName@version`, with `clear()` / `clearKey()` for rotation and tests. Caches `null` results. Never logs values.
|
|
18
|
+
- **`ConfigurationApp` pluggable permissions** — `permissions: {read?, update?, meta?, listSecrets?}` accepts terreno permission functions (e.g. `[IsStaff]`), AND-combined like `modelRouter`. Defaults to admin-only for every route.
|
|
19
|
+
- **`ConfigurationApp` lifecycle hooks** — `preUpdate(body, req)` (validate/normalize) and `postUpdate(config, prevValue, req)` (audit logging). Both payloads have secret values redacted.
|
|
20
|
+
- **`flattenToDotPaths`** — exported helper used by `updateConfig`.
|
|
21
|
+
|
|
22
|
+
### Migration
|
|
23
|
+
|
|
24
|
+
- If you relied on `list-secrets` to populate secret values into the configuration document, stop. Resolve secrets on-demand at runtime via `Model.resolveSecrets(provider)` (returns an in-memory `Map`) and read them from memory; never persist them.
|
|
25
|
+
- If you depended on the `_singleton` unique index, pass `configurationPlugin(schema, {enforceSingletonIndex: true})`.
|
|
26
|
+
- For GCP-with-env-fallback and caching, compose `new CachingSecretProvider(new CompositeSecretProvider([gcp, env]), {ttlMs})`.
|
|
27
|
+
|
|
3
28
|
## 0.16.0
|
|
4
29
|
|
|
5
30
|
### Added
|
package/dist/api.test.js
CHANGED
|
@@ -2545,14 +2545,20 @@ var transformers_1 = require("./transformers");
|
|
|
2545
2545
|
});
|
|
2546
2546
|
}); });
|
|
2547
2547
|
(0, bun_test_1.it)("returns 409 when precise conflict timestamp is older than doc.updated", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
2548
|
+
var ifUnmodifiedSince;
|
|
2548
2549
|
return __generator(this, function (_a) {
|
|
2549
2550
|
switch (_a.label) {
|
|
2550
|
-
case 0:
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2551
|
+
case 0:
|
|
2552
|
+
ifUnmodifiedSince = luxon_1.DateTime.fromISO("2025-06-15T12:00:01.000Z").toHTTP();
|
|
2553
|
+
if (ifUnmodifiedSince === null) {
|
|
2554
|
+
throw new Error("expected HTTP If-Unmodified-Since value");
|
|
2555
|
+
}
|
|
2556
|
+
return [4 /*yield*/, agent
|
|
2557
|
+
.patch("/food/".concat(spinach._id))
|
|
2558
|
+
.set("If-Unmodified-Since", ifUnmodifiedSince)
|
|
2559
|
+
.set("X-Unmodified-Since-ISO", "2025-06-15T11:59:59.500Z")
|
|
2560
|
+
.send({ name: "Precise Stale" })
|
|
2561
|
+
.expect(409)];
|
|
2556
2562
|
case 1:
|
|
2557
2563
|
_a.sent();
|
|
2558
2564
|
return [2 /*return*/];
|
|
@@ -2560,15 +2566,19 @@ var transformers_1 = require("./transformers");
|
|
|
2560
2566
|
});
|
|
2561
2567
|
}); });
|
|
2562
2568
|
(0, bun_test_1.it)("falls back to doc.created when doc.updated is unavailable", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
2563
|
-
var res;
|
|
2569
|
+
var ifUnmodifiedSince, res;
|
|
2564
2570
|
return __generator(this, function (_a) {
|
|
2565
2571
|
switch (_a.label) {
|
|
2566
2572
|
case 0: return [4 /*yield*/, tests_1.FoodModel.collection.updateOne({ _id: spinach._id }, { $unset: { updated: "" } })];
|
|
2567
2573
|
case 1:
|
|
2568
2574
|
_a.sent();
|
|
2575
|
+
ifUnmodifiedSince = luxon_1.DateTime.fromISO("2025-06-15T11:59:59.999Z").toHTTP();
|
|
2576
|
+
if (ifUnmodifiedSince === null) {
|
|
2577
|
+
throw new Error("expected HTTP If-Unmodified-Since value");
|
|
2578
|
+
}
|
|
2569
2579
|
return [4 /*yield*/, agent
|
|
2570
2580
|
.patch("/food/".concat(spinach._id))
|
|
2571
|
-
.set("If-Unmodified-Since",
|
|
2581
|
+
.set("If-Unmodified-Since", ifUnmodifiedSince)
|
|
2572
2582
|
.send({ name: "Created Fallback" })
|
|
2573
2583
|
.expect(409)];
|
|
2574
2584
|
case 2:
|
package/dist/auth.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ export interface UserModel extends Model<User> {
|
|
|
22
22
|
export interface GenerateTokensOptions {
|
|
23
23
|
sessionId?: string;
|
|
24
24
|
}
|
|
25
|
-
export declare
|
|
26
|
-
export declare
|
|
25
|
+
export declare const authenticateMiddleware: (anonymous?: boolean) => (req: express.Request, res: express.Response, next: express.NextFunction) => any;
|
|
26
|
+
export declare const signupUser: (userModel: UserModel, email: string, password: string, body?: Record<string, unknown>) => Promise<any>;
|
|
27
27
|
/**
|
|
28
28
|
* Generates both an access token (JWT) and a refresh token for a given user.
|
|
29
29
|
*
|
|
@@ -50,6 +50,6 @@ export declare const generateTokens: (user: unknown, authOptions?: AuthOptions,
|
|
|
50
50
|
sessionId: string;
|
|
51
51
|
token: string;
|
|
52
52
|
}>;
|
|
53
|
-
export declare
|
|
54
|
-
export declare
|
|
55
|
-
export declare
|
|
53
|
+
export declare const setupAuth: (app: express.Application, userModel: UserModel) => void;
|
|
54
|
+
export declare const addAuthRoutes: (app: express.Application, userModel: UserModel, authOptions?: AuthOptions) => void;
|
|
55
|
+
export declare const addMeRoutes: (app: express.Application, userModel: UserModel, _authOptions?: AuthOptions) => void;
|
package/dist/auth.js
CHANGED
|
@@ -86,12 +86,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
86
86
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
87
87
|
};
|
|
88
88
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
89
|
-
exports.generateTokens = void 0;
|
|
90
|
-
exports.authenticateMiddleware = authenticateMiddleware;
|
|
91
|
-
exports.signupUser = signupUser;
|
|
92
|
-
exports.setupAuth = setupAuth;
|
|
93
|
-
exports.addAuthRoutes = addAuthRoutes;
|
|
94
|
-
exports.addMeRoutes = addMeRoutes;
|
|
89
|
+
exports.addMeRoutes = exports.addAuthRoutes = exports.setupAuth = exports.generateTokens = exports.signupUser = exports.authenticateMiddleware = void 0;
|
|
95
90
|
var node_crypto_1 = require("node:crypto");
|
|
96
91
|
var express_1 = __importDefault(require("express"));
|
|
97
92
|
var jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
@@ -103,7 +98,7 @@ var passport_local_1 = require("passport-local");
|
|
|
103
98
|
var errors_1 = require("./errors");
|
|
104
99
|
var logger_1 = require("./logger");
|
|
105
100
|
var requestContext_1 = require("./requestContext");
|
|
106
|
-
function
|
|
101
|
+
var authenticateMiddleware = function (anonymous) {
|
|
107
102
|
if (anonymous === void 0) { anonymous = false; }
|
|
108
103
|
var strategies = ["jwt"];
|
|
109
104
|
if (anonymous) {
|
|
@@ -120,45 +115,45 @@ function authenticateMiddleware(anonymous) {
|
|
|
120
115
|
}
|
|
121
116
|
return passportAuth(req, res, next);
|
|
122
117
|
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
});
|
|
118
|
+
};
|
|
119
|
+
exports.authenticateMiddleware = authenticateMiddleware;
|
|
120
|
+
var signupUser = function (userModel, email, password, body) { return __awaiter(void 0, void 0, void 0, function () {
|
|
121
|
+
var _a, _email, _password, bodyRest, user, error_1, error_2, message;
|
|
122
|
+
return __generator(this, function (_b) {
|
|
123
|
+
switch (_b.label) {
|
|
124
|
+
case 0:
|
|
125
|
+
_a = body !== null && body !== void 0 ? body : {}, _email = _a.email, _password = _a.password, bodyRest = __rest(_a, ["email", "password"]);
|
|
126
|
+
_b.label = 1;
|
|
127
|
+
case 1:
|
|
128
|
+
_b.trys.push([1, 8, , 9]);
|
|
129
|
+
return [4 /*yield*/, userModel.register(__assign({ email: email }, bodyRest), password)];
|
|
130
|
+
case 2:
|
|
131
|
+
user = _b.sent();
|
|
132
|
+
if (!user.postCreate) return [3 /*break*/, 6];
|
|
133
|
+
_b.label = 3;
|
|
134
|
+
case 3:
|
|
135
|
+
_b.trys.push([3, 5, , 6]);
|
|
136
|
+
return [4 /*yield*/, user.postCreate(bodyRest)];
|
|
137
|
+
case 4:
|
|
138
|
+
_b.sent();
|
|
139
|
+
return [3 /*break*/, 6];
|
|
140
|
+
case 5:
|
|
141
|
+
error_1 = _b.sent();
|
|
142
|
+
logger_1.logger.error("Error in user.postCreate: ".concat(error_1));
|
|
143
|
+
throw error_1;
|
|
144
|
+
case 6: return [4 /*yield*/, user.save()];
|
|
145
|
+
case 7:
|
|
146
|
+
_b.sent();
|
|
147
|
+
return [2 /*return*/, user];
|
|
148
|
+
case 8:
|
|
149
|
+
error_2 = _b.sent();
|
|
150
|
+
message = (0, errors_1.errorMessage)(error_2);
|
|
151
|
+
throw new errors_1.APIError({ title: message });
|
|
152
|
+
case 9: return [2 /*return*/];
|
|
153
|
+
}
|
|
160
154
|
});
|
|
161
|
-
}
|
|
155
|
+
}); };
|
|
156
|
+
exports.signupUser = signupUser;
|
|
162
157
|
/**
|
|
163
158
|
* Generates both an access token (JWT) and a refresh token for a given user.
|
|
164
159
|
*
|
|
@@ -188,7 +183,7 @@ var generateTokens = function (user_1, authOptions_1) {
|
|
|
188
183
|
return __generator(this, function (_b) {
|
|
189
184
|
tokenSecretOrKey = process.env.TOKEN_SECRET;
|
|
190
185
|
if (!tokenSecretOrKey) {
|
|
191
|
-
throw new
|
|
186
|
+
throw new errors_1.APIError({ status: 500, title: "TOKEN_SECRET must be set in env." });
|
|
192
187
|
}
|
|
193
188
|
tokenUser = user;
|
|
194
189
|
if (!(tokenUser === null || tokenUser === void 0 ? void 0 : tokenUser._id)) {
|
|
@@ -253,15 +248,14 @@ var generateTokens = function (user_1, authOptions_1) {
|
|
|
253
248
|
};
|
|
254
249
|
exports.generateTokens = generateTokens;
|
|
255
250
|
// TODO allow customization
|
|
256
|
-
function
|
|
257
|
-
var _this = this;
|
|
251
|
+
var setupAuth = function (app, userModel) {
|
|
258
252
|
passport_1.default.use(new passport_anonymous_1.Strategy());
|
|
259
253
|
passport_1.default.use(userModel.createStrategy());
|
|
260
254
|
passport_1.default.use("signup", new passport_local_1.Strategy({
|
|
261
255
|
passReqToCallback: true,
|
|
262
256
|
passwordField: "password",
|
|
263
257
|
usernameField: "email",
|
|
264
|
-
}, function (req, email, password, done) { return __awaiter(
|
|
258
|
+
}, function (req, email, password, done) { return __awaiter(void 0, void 0, void 0, function () {
|
|
265
259
|
var _a, _b, error_3;
|
|
266
260
|
return __generator(this, function (_c) {
|
|
267
261
|
switch (_c.label) {
|
|
@@ -269,7 +263,7 @@ function setupAuth(app, userModel) {
|
|
|
269
263
|
_c.trys.push([0, 2, , 3]);
|
|
270
264
|
_a = done;
|
|
271
265
|
_b = [undefined];
|
|
272
|
-
return [4 /*yield*/, signupUser(userModel, email, password, req.body)];
|
|
266
|
+
return [4 /*yield*/, (0, exports.signupUser)(userModel, email, password, req.body)];
|
|
273
267
|
case 1:
|
|
274
268
|
_a.apply(void 0, _b.concat([_c.sent()]));
|
|
275
269
|
return [3 /*break*/, 3];
|
|
@@ -281,7 +275,7 @@ function setupAuth(app, userModel) {
|
|
|
281
275
|
});
|
|
282
276
|
}); }));
|
|
283
277
|
if (!userModel.createStrategy) {
|
|
284
|
-
throw new
|
|
278
|
+
throw new errors_1.APIError({ status: 500, title: "setupAuth userModel must have .createStrategy()" });
|
|
285
279
|
}
|
|
286
280
|
var customTokenExtractor = function (req) {
|
|
287
281
|
var _a, _b, _c;
|
|
@@ -300,14 +294,14 @@ function setupAuth(app, userModel) {
|
|
|
300
294
|
}
|
|
301
295
|
var secretOrKey = process.env.TOKEN_SECRET;
|
|
302
296
|
if (!secretOrKey) {
|
|
303
|
-
throw new
|
|
297
|
+
throw new errors_1.APIError({ status: 500, title: "TOKEN_SECRET must be set in env." });
|
|
304
298
|
}
|
|
305
299
|
var jwtOpts = {
|
|
306
300
|
issuer: process.env.TOKEN_ISSUER,
|
|
307
301
|
jwtFromRequest: customTokenExtractor,
|
|
308
302
|
secretOrKey: secretOrKey,
|
|
309
303
|
};
|
|
310
|
-
passport_1.default.use("jwt", new passport_jwt_1.Strategy(jwtOpts, function (jwtPayload, done) { return __awaiter(
|
|
304
|
+
passport_1.default.use("jwt", new passport_jwt_1.Strategy(jwtOpts, function (jwtPayload, done) { return __awaiter(void 0, void 0, void 0, function () {
|
|
311
305
|
var user, error_4;
|
|
312
306
|
return __generator(this, function (_a) {
|
|
313
307
|
switch (_a.label) {
|
|
@@ -346,82 +340,79 @@ function setupAuth(app, userModel) {
|
|
|
346
340
|
}
|
|
347
341
|
// Adds req.user to the request. This may wind up duplicating requests with passport,
|
|
348
342
|
// but passport doesn't give us req.user early enough.
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
});
|
|
343
|
+
var decodeJWTMiddleware = function (req, res, next) { return __awaiter(void 0, void 0, void 0, function () {
|
|
344
|
+
var token, decoded, userText, expiredAt, message, details, sessionId, user, error_5;
|
|
345
|
+
var _a, _b, _c, _d;
|
|
346
|
+
return __generator(this, function (_e) {
|
|
347
|
+
switch (_e.label) {
|
|
348
|
+
case 0:
|
|
349
|
+
if (!process.env.TOKEN_SECRET) {
|
|
350
|
+
return [2 /*return*/, next()];
|
|
351
|
+
}
|
|
352
|
+
// Allow requests with a "Secret" prefix to pass through since this is a string value,
|
|
353
|
+
// not a jwt that needs to be decoded
|
|
354
|
+
if (((_b = (_a = req === null || req === void 0 ? void 0 : req.headers) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.split(" ")[0]) === "Secret") {
|
|
355
|
+
return [2 /*return*/, next()];
|
|
356
|
+
}
|
|
357
|
+
token = customTokenExtractor(req);
|
|
358
|
+
// For some reason, our app will happily put null into the authorization header when logging
|
|
359
|
+
// out then back in.
|
|
360
|
+
if (!token || token === "null" || token === "undefined") {
|
|
361
|
+
return [2 /*return*/, next()];
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
decoded = jsonwebtoken_1.default.verify(token, process.env.TOKEN_SECRET, {
|
|
365
|
+
issuer: process.env.TOKEN_ISSUER,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
userText = ((_c = req.user) === null || _c === void 0 ? void 0 : _c._id) ? " for user ".concat(req.user._id, " ") : "";
|
|
370
|
+
expiredAt = error && typeof error === "object" && "expiredAt" in error
|
|
371
|
+
? error.expiredAt
|
|
372
|
+
: undefined;
|
|
373
|
+
message = (0, errors_1.errorMessage)(error);
|
|
374
|
+
details = "[jwt] Error decoding token".concat(userText, ": ").concat(error, ", expired at ").concat(expiredAt, ", current time: ").concat(Date.now());
|
|
375
|
+
logger_1.logger.debug(details);
|
|
376
|
+
return [2 /*return*/, res.status(401).json({ details: details, message: message })];
|
|
377
|
+
}
|
|
378
|
+
if (!(decoded === null || decoded === void 0 ? void 0 : decoded.id)) return [3 /*break*/, 4];
|
|
379
|
+
sessionId = (0, requestContext_1.getSessionIdFromJwtPayload)(decoded);
|
|
380
|
+
req.authTokenPayload = decoded;
|
|
381
|
+
if (sessionId) {
|
|
382
|
+
req.sessionId = sessionId;
|
|
383
|
+
(0, requestContext_1.setRequestContext)({ sessionId: sessionId });
|
|
384
|
+
}
|
|
385
|
+
_e.label = 1;
|
|
386
|
+
case 1:
|
|
387
|
+
_e.trys.push([1, 3, , 4]);
|
|
388
|
+
return [4 /*yield*/, userModel.findById(decoded.id)];
|
|
389
|
+
case 2:
|
|
390
|
+
user = _e.sent();
|
|
391
|
+
req.user = user;
|
|
392
|
+
(0, requestContext_1.updateRequestContextFromRequest)(req, res);
|
|
393
|
+
if ((_d = req.user) === null || _d === void 0 ? void 0 : _d.disabled) {
|
|
394
|
+
logger_1.logger.warn("[jwt] User ".concat(req.user.id, " is disabled"));
|
|
395
|
+
return [2 /*return*/, res.status(401).json({ status: 401, title: "User is disabled" })];
|
|
396
|
+
}
|
|
397
|
+
return [3 /*break*/, 4];
|
|
398
|
+
case 3:
|
|
399
|
+
error_5 = _e.sent();
|
|
400
|
+
logger_1.logger.warn("[jwt] Error finding user from id: ".concat(error_5));
|
|
401
|
+
return [3 /*break*/, 4];
|
|
402
|
+
case 4: return [2 /*return*/, next()];
|
|
403
|
+
}
|
|
412
404
|
});
|
|
413
|
-
}
|
|
405
|
+
}); };
|
|
414
406
|
app.use(decodeJWTMiddleware);
|
|
415
407
|
// biome-ignore lint/suspicious/noExplicitAny: express 5 type for urlencoded doesn't match RequestHandler
|
|
416
408
|
app.use(express_1.default.urlencoded({ extended: false }));
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
|
|
409
|
+
};
|
|
410
|
+
exports.setupAuth = setupAuth;
|
|
411
|
+
var addAuthRoutes = function (app, userModel, authOptions) {
|
|
420
412
|
var router = express_1.default.Router();
|
|
421
|
-
router.post("/login", function (req, res, next) { return __awaiter(
|
|
422
|
-
var _this = this;
|
|
413
|
+
router.post("/login", function (req, res, next) { return __awaiter(void 0, void 0, void 0, function () {
|
|
423
414
|
return __generator(this, function (_a) {
|
|
424
|
-
passport_1.default.authenticate("local", { session: false }, function (err, user, info) { return __awaiter(
|
|
415
|
+
passport_1.default.authenticate("local", { session: false }, function (err, user, info) { return __awaiter(void 0, void 0, void 0, function () {
|
|
425
416
|
var tokens;
|
|
426
417
|
return __generator(this, function (_a) {
|
|
427
418
|
switch (_a.label) {
|
|
@@ -453,7 +444,7 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
453
444
|
return [2 /*return*/];
|
|
454
445
|
});
|
|
455
446
|
}); });
|
|
456
|
-
router.post("/refresh_token", function (req, res) { return __awaiter(
|
|
447
|
+
router.post("/refresh_token", function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
457
448
|
var refreshTokenSecretOrKey, decoded, message, user, sessionId, tokens;
|
|
458
449
|
var _a, _b, _c, _d;
|
|
459
450
|
return __generator(this, function (_e) {
|
|
@@ -503,7 +494,7 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
503
494
|
}); });
|
|
504
495
|
var signupDisabled = process.env.SIGNUP_DISABLED === "true";
|
|
505
496
|
if (!signupDisabled) {
|
|
506
|
-
router.post("/signup", passport_1.default.authenticate("signup", { failWithError: true, session: false }), function (req, res) { return __awaiter(
|
|
497
|
+
router.post("/signup", passport_1.default.authenticate("signup", { failWithError: true, session: false }), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
507
498
|
var tokens;
|
|
508
499
|
var _a, _b;
|
|
509
500
|
return __generator(this, function (_c) {
|
|
@@ -527,11 +518,11 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
527
518
|
}
|
|
528
519
|
app.set("etag", false);
|
|
529
520
|
app.use("/auth", router);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
521
|
+
};
|
|
522
|
+
exports.addAuthRoutes = addAuthRoutes;
|
|
523
|
+
var addMeRoutes = function (app, userModel, _authOptions) {
|
|
533
524
|
var router = express_1.default.Router();
|
|
534
|
-
router.get("/me", authenticateMiddleware(), function (req, res) { return __awaiter(
|
|
525
|
+
router.get("/me", (0, exports.authenticateMiddleware)(), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
535
526
|
var data, dataObject;
|
|
536
527
|
var _a;
|
|
537
528
|
return __generator(this, function (_b) {
|
|
@@ -554,7 +545,7 @@ function addMeRoutes(app, userModel, _authOptions) {
|
|
|
554
545
|
}
|
|
555
546
|
});
|
|
556
547
|
}); });
|
|
557
|
-
router.patch("/me", authenticateMiddleware(), function (req, res) { return __awaiter(
|
|
548
|
+
router.patch("/me", (0, exports.authenticateMiddleware)(), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
558
549
|
var doc, dataObject, error_6, message;
|
|
559
550
|
var _a;
|
|
560
551
|
return __generator(this, function (_b) {
|
|
@@ -590,4 +581,5 @@ function addMeRoutes(app, userModel, _authOptions) {
|
|
|
590
581
|
app.set("etag", false);
|
|
591
582
|
app.use("/auth", router);
|
|
592
583
|
app.use(errors_1.apiErrorMiddleware);
|
|
593
|
-
}
|
|
584
|
+
};
|
|
585
|
+
exports.addMeRoutes = addMeRoutes;
|