@proteinjs/user-server 1.11.1 → 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 (35) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/generated/index.d.ts.map +1 -1
  3. package/dist/generated/index.js +3 -1
  4. package/dist/generated/index.js.map +1 -1
  5. package/dist/src/migrations/SweepMalformedAccessGrants.d.ts +76 -0
  6. package/dist/src/migrations/SweepMalformedAccessGrants.d.ts.map +1 -0
  7. package/dist/src/migrations/SweepMalformedAccessGrants.js +354 -0
  8. package/dist/src/migrations/SweepMalformedAccessGrants.js.map +1 -0
  9. package/dist/src/routes/devLogin.d.ts +5 -0
  10. package/dist/src/routes/devLogin.d.ts.map +1 -1
  11. package/dist/src/routes/devLogin.js +13 -0
  12. package/dist/src/routes/devLogin.js.map +1 -1
  13. package/dist/src/services/Roles.d.ts +2 -0
  14. package/dist/src/services/Roles.d.ts.map +1 -1
  15. package/dist/src/services/Roles.js +22 -2
  16. package/dist/src/services/Roles.js.map +1 -1
  17. package/dist/test/DevLogin.test.js +41 -0
  18. package/dist/test/DevLogin.test.js.map +1 -1
  19. package/dist/test/MachineAccounts.integration.test.js +91 -7
  20. package/dist/test/MachineAccounts.integration.test.js.map +1 -1
  21. package/dist/test/Roles.integration.test.js +141 -2
  22. package/dist/test/Roles.integration.test.js.map +1 -1
  23. package/dist/test/SweepMalformedAccessGrants.integration.test.d.ts +2 -0
  24. package/dist/test/SweepMalformedAccessGrants.integration.test.d.ts.map +1 -0
  25. package/dist/test/SweepMalformedAccessGrants.integration.test.js +424 -0
  26. package/dist/test/SweepMalformedAccessGrants.integration.test.js.map +1 -0
  27. package/generated/index.ts +3 -1
  28. package/package.json +4 -3
  29. package/src/migrations/SweepMalformedAccessGrants.ts +229 -0
  30. package/src/routes/devLogin.ts +15 -0
  31. package/src/services/Roles.ts +28 -2
  32. package/test/DevLogin.test.ts +26 -0
  33. package/test/MachineAccounts.integration.test.ts +76 -33
  34. package/test/Roles.integration.test.ts +67 -2
  35. package/test/SweepMalformedAccessGrants.integration.test.ts +255 -0
@@ -0,0 +1,354 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
50
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
51
+ var m = o[Symbol.asyncIterator], i;
52
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
53
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
54
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.SweepMalformedAccessGrants = void 0;
58
+ var db_1 = require("@proteinjs/db");
59
+ var user_1 = require("@proteinjs/user");
60
+ var logger_1 = require("@proteinjs/logger");
61
+ /**
62
+ * ONE-TIME SWEEP of malformed access_grant residue — rows whose `principal` or `resource`
63
+ * reference is NULL. The AccessGrant well-formedness invariant (`AccessGrantTable.assertWellFormed`)
64
+ * now refuses that shape at insert, and the session-less scope-root bootstrap no longer mints it;
65
+ * this migration clears what the two producers left behind before the fix (the test environment
66
+ * held one; app Deploy to Test 32614670162 crashed on it).
67
+ *
68
+ * The sweep's predicate is the invariant's exact complement (`principal IS NULL OR resource IS
69
+ * NULL`), and it rides BOTH the find and the delete — a well-formed row cannot be selected by the
70
+ * statement that deletes, whatever the id list. Deletes go through the system Db by id, so the
71
+ * registered after-delete watchers fire (a grantee's content_reference cleanup rides
72
+ * `ContentReferenceAccessGrantTableWatcher`). Idempotent: a re-run finds nothing.
73
+ *
74
+ * DANGLING references are a separate class and are NOT deleted here: a well-formed grant whose
75
+ * principal user or resource row was purged out from under it. Those are REPORTED (log +
76
+ * migration output) so the purge paths that strand them can be named; a delete would be a
77
+ * symptom patch on a producer this migration does not own.
78
+ *
79
+ * App-service/system-db path only — never raw Spanner.
80
+ */
81
+ var SweepMalformedAccessGrants = /** @class */ (function () {
82
+ function SweepMalformedAccessGrants() {
83
+ var _this = this;
84
+ this.table = db_1.tables.Migration;
85
+ this.record = {
86
+ id: '2b7e4d0c-5f1a-4c3e-9b8d-6a2f1e0c7d45',
87
+ description: 'Sweep malformed access_grant rows (NULL principal or NULL resource — the well-formedness invariant’s complement); report dangling references, no delete.',
88
+ run: function () { return __awaiter(_this, void 0, void 0, function () {
89
+ var logger, dry, real, dangling, output;
90
+ return __generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0:
93
+ logger = new logger_1.Logger({ name: SweepMalformedAccessGrants.name });
94
+ return [4 /*yield*/, this.sweep({ dryRun: true })];
95
+ case 1:
96
+ dry = _a.sent();
97
+ return [4 /*yield*/, this.sweep({ dryRun: false })];
98
+ case 2:
99
+ real = _a.sent();
100
+ return [4 /*yield*/, this.reportDangling()];
101
+ case 3:
102
+ dangling = _a.sent();
103
+ output = {
104
+ malformed: real.malformed,
105
+ malformedDryRun: dry.malformed,
106
+ danglingPrincipal: dangling.danglingPrincipal,
107
+ danglingResource: dangling.danglingResource,
108
+ malformedRows: real.rows,
109
+ danglingRows: dangling.rows,
110
+ };
111
+ logger.info({ message: 'SweepMalformedAccessGrants completed', obj: output });
112
+ return [2 /*return*/, output];
113
+ }
114
+ });
115
+ }); },
116
+ };
117
+ }
118
+ /** Find (and unless `dryRun`, delete) every malformed grant. Each row is logged either way. */
119
+ SweepMalformedAccessGrants.prototype.sweep = function (options) {
120
+ return __awaiter(this, void 0, void 0, function () {
121
+ var dryRun, logger, db, findQb, malformed, rows, _i, rows_1, row, _a, malformed_1, grant, deleteQb, result;
122
+ var _this = this;
123
+ return __generator(this, function (_b) {
124
+ switch (_b.label) {
125
+ case 0:
126
+ dryRun = options.dryRun;
127
+ logger = new logger_1.Logger({ name: SweepMalformedAccessGrants.name });
128
+ db = (0, db_1.getDbAsSystem)();
129
+ findQb = this.malformedPredicate(new db_1.QueryBuilderFactory().getQueryBuilder(user_1.tables.AccessGrant)).sort([
130
+ { field: 'created' },
131
+ ]);
132
+ return [4 /*yield*/, db.query(user_1.tables.AccessGrant, findQb)];
133
+ case 1:
134
+ malformed = _b.sent();
135
+ rows = malformed.map(function (grant) { return _this.toRow(grant); });
136
+ for (_i = 0, rows_1 = rows; _i < rows_1.length; _i++) {
137
+ row = rows_1[_i];
138
+ logger.info({
139
+ message: dryRun ? 'Malformed access_grant (dry run)' : 'Deleting malformed access_grant',
140
+ obj: row,
141
+ });
142
+ }
143
+ if (!!dryRun) return [3 /*break*/, 5];
144
+ _a = 0, malformed_1 = malformed;
145
+ _b.label = 2;
146
+ case 2:
147
+ if (!(_a < malformed_1.length)) return [3 /*break*/, 5];
148
+ grant = malformed_1[_a];
149
+ deleteQb = this.malformedPredicate(new db_1.QueryBuilderFactory().getQueryBuilder(user_1.tables.AccessGrant, { id: grant.id }));
150
+ return [4 /*yield*/, db.delete(user_1.tables.AccessGrant, deleteQb)];
151
+ case 3:
152
+ _b.sent();
153
+ _b.label = 4;
154
+ case 4:
155
+ _a++;
156
+ return [3 /*break*/, 2];
157
+ case 5:
158
+ result = { malformed: rows.length, rows: rows, dryRun: dryRun };
159
+ logger.info({ message: dryRun ? 'Sweep dry run' : 'Sweep pass', obj: { malformed: rows.length, dryRun: dryRun } });
160
+ return [2 /*return*/, result];
161
+ }
162
+ });
163
+ });
164
+ };
165
+ /**
166
+ * Report-only scan for well-formed grants whose principal or resource row no longer exists —
167
+ * the purged-user / purged-resource class. Nothing is deleted.
168
+ */
169
+ SweepMalformedAccessGrants.prototype.reportDangling = function () {
170
+ var _a, e_1, _b, _c;
171
+ var _d, _e, _f, _g;
172
+ return __awaiter(this, void 0, void 0, function () {
173
+ var logger, db, grants, principalIds, resourceIdsByTable, _h, _j, _k, grant, principalId, resourceId, resourceTable, e_1_1, existingPrincipals, existingResourcesByTable, _loop_1, this_1, _i, _l, tableName, report, _m, grants_1, grant, resourceTable, existingResources, reason, row;
174
+ return __generator(this, function (_o) {
175
+ switch (_o.label) {
176
+ case 0:
177
+ logger = new logger_1.Logger({ name: SweepMalformedAccessGrants.name });
178
+ db = (0, db_1.getDbAsSystem)();
179
+ grants = [];
180
+ principalIds = new Set();
181
+ resourceIdsByTable = new Map();
182
+ _o.label = 1;
183
+ case 1:
184
+ _o.trys.push([1, 6, 7, 12]);
185
+ _h = true, _j = __asyncValues(new db_1.RecordIterator(user_1.tables.AccessGrant, {}, 200, db));
186
+ _o.label = 2;
187
+ case 2: return [4 /*yield*/, _j.next()];
188
+ case 3:
189
+ if (!(_k = _o.sent(), _a = _k.done, !_a)) return [3 /*break*/, 5];
190
+ _c = _k.value;
191
+ _h = false;
192
+ grant = _c;
193
+ principalId = (_d = grant.principal) === null || _d === void 0 ? void 0 : _d._id;
194
+ resourceId = (_e = grant.resource) === null || _e === void 0 ? void 0 : _e._id;
195
+ if (!principalId || !resourceId) {
196
+ return [3 /*break*/, 4]; // the malformed class — `sweep` owns it
197
+ }
198
+ grants.push(grant);
199
+ principalIds.add(principalId);
200
+ resourceTable = (_f = grant.resourceTable) !== null && _f !== void 0 ? _f : grant.resource._table;
201
+ if (!resourceIdsByTable.has(resourceTable)) {
202
+ resourceIdsByTable.set(resourceTable, new Set());
203
+ }
204
+ resourceIdsByTable.get(resourceTable).add(resourceId);
205
+ _o.label = 4;
206
+ case 4:
207
+ _h = true;
208
+ return [3 /*break*/, 2];
209
+ case 5: return [3 /*break*/, 12];
210
+ case 6:
211
+ e_1_1 = _o.sent();
212
+ e_1 = { error: e_1_1 };
213
+ return [3 /*break*/, 12];
214
+ case 7:
215
+ _o.trys.push([7, , 10, 11]);
216
+ if (!(!_h && !_a && (_b = _j.return))) return [3 /*break*/, 9];
217
+ return [4 /*yield*/, _b.call(_j)];
218
+ case 8:
219
+ _o.sent();
220
+ _o.label = 9;
221
+ case 9: return [3 /*break*/, 11];
222
+ case 10:
223
+ if (e_1) throw e_1.error;
224
+ return [7 /*endfinally*/];
225
+ case 11: return [7 /*endfinally*/];
226
+ case 12: return [4 /*yield*/, this.existingIds(user_1.tables.User, principalIds)];
227
+ case 13:
228
+ existingPrincipals = _o.sent();
229
+ existingResourcesByTable = new Map();
230
+ _loop_1 = function (tableName) {
231
+ var table, _p, _q, _r, _s;
232
+ return __generator(this, function (_t) {
233
+ switch (_t.label) {
234
+ case 0:
235
+ table = (0, db_1.getTables)().find(function (candidate) { return candidate.name === tableName; });
236
+ _q = (_p = existingResourcesByTable).set;
237
+ _r = [tableName];
238
+ if (!table) return [3 /*break*/, 2];
239
+ return [4 /*yield*/, this_1.existingIds(table, resourceIdsByTable.get(tableName))];
240
+ case 1:
241
+ _s = _t.sent();
242
+ return [3 /*break*/, 3];
243
+ case 2:
244
+ _s = null;
245
+ _t.label = 3;
246
+ case 3:
247
+ _q.apply(_p, _r.concat([_s]));
248
+ return [2 /*return*/];
249
+ }
250
+ });
251
+ };
252
+ this_1 = this;
253
+ _i = 0, _l = Array.from(resourceIdsByTable.keys());
254
+ _o.label = 14;
255
+ case 14:
256
+ if (!(_i < _l.length)) return [3 /*break*/, 17];
257
+ tableName = _l[_i];
258
+ return [5 /*yield**/, _loop_1(tableName)];
259
+ case 15:
260
+ _o.sent();
261
+ _o.label = 16;
262
+ case 16:
263
+ _i++;
264
+ return [3 /*break*/, 14];
265
+ case 17:
266
+ report = { danglingPrincipal: 0, danglingResource: 0, rows: [] };
267
+ for (_m = 0, grants_1 = grants; _m < grants_1.length; _m++) {
268
+ grant = grants_1[_m];
269
+ resourceTable = (_g = grant.resourceTable) !== null && _g !== void 0 ? _g : grant.resource._table;
270
+ existingResources = existingResourcesByTable.get(resourceTable);
271
+ reason = void 0;
272
+ if (!existingPrincipals.has(grant.principal._id)) {
273
+ reason = 'principal missing';
274
+ report.danglingPrincipal++;
275
+ }
276
+ else if (existingResources === null) {
277
+ reason = 'resource table not registered';
278
+ report.danglingResource++;
279
+ }
280
+ else if (!existingResources.has(grant.resource._id)) {
281
+ reason = 'resource missing';
282
+ report.danglingResource++;
283
+ }
284
+ if (!reason) {
285
+ continue;
286
+ }
287
+ row = __assign(__assign({}, this.toRow(grant)), { principal: grant.principal._id, resource: grant.resource._id, reason: reason });
288
+ report.rows.push(row);
289
+ logger.warn({ message: 'Dangling access_grant (report only, not deleted)', obj: row });
290
+ }
291
+ logger.info({
292
+ message: 'Dangling access_grant report',
293
+ obj: { danglingPrincipal: report.danglingPrincipal, danglingResource: report.danglingResource },
294
+ });
295
+ return [2 /*return*/, report];
296
+ }
297
+ });
298
+ });
299
+ };
300
+ /** The well-formedness invariant's exact complement: a NULL principal or a NULL resource. */
301
+ SweepMalformedAccessGrants.prototype.malformedPredicate = function (qb) {
302
+ return qb.or([
303
+ { field: 'principal', operator: 'IS NULL' },
304
+ { field: 'resource', operator: 'IS NULL' },
305
+ ]);
306
+ };
307
+ /** Which of `ids` exist in `table`, resolved as system in bounded IN chunks. */
308
+ SweepMalformedAccessGrants.prototype.existingIds = function (table, ids) {
309
+ return __awaiter(this, void 0, void 0, function () {
310
+ var existing, all, chunkSize, start, chunk, qb, found, _i, found_1, record;
311
+ return __generator(this, function (_a) {
312
+ switch (_a.label) {
313
+ case 0:
314
+ existing = new Set();
315
+ all = Array.from(ids);
316
+ chunkSize = 200;
317
+ start = 0;
318
+ _a.label = 1;
319
+ case 1:
320
+ if (!(start < all.length)) return [3 /*break*/, 4];
321
+ chunk = all.slice(start, start + chunkSize);
322
+ qb = new db_1.QueryBuilderFactory()
323
+ .getQueryBuilder(table)
324
+ .select({ fields: ['id'] })
325
+ .condition({ field: 'id', operator: 'IN', value: chunk });
326
+ return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(table, qb)];
327
+ case 2:
328
+ found = (_a.sent());
329
+ for (_i = 0, found_1 = found; _i < found_1.length; _i++) {
330
+ record = found_1[_i];
331
+ existing.add(record.id);
332
+ }
333
+ _a.label = 3;
334
+ case 3:
335
+ start += chunkSize;
336
+ return [3 /*break*/, 1];
337
+ case 4: return [2 /*return*/, existing];
338
+ }
339
+ });
340
+ });
341
+ };
342
+ SweepMalformedAccessGrants.prototype.toRow = function (grant) {
343
+ var _a;
344
+ return {
345
+ id: grant.id,
346
+ resourceTable: grant.resourceTable,
347
+ accessLevel: grant.accessLevel,
348
+ created: (_a = grant.created) === null || _a === void 0 ? void 0 : _a.toISOString(),
349
+ };
350
+ };
351
+ return SweepMalformedAccessGrants;
352
+ }());
353
+ exports.SweepMalformedAccessGrants = SweepMalformedAccessGrants;
354
+ //# sourceMappingURL=SweepMalformedAccessGrants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SweepMalformedAccessGrants.js","sourceRoot":"","sources":["../../../src/migrations/SweepMalformedAccessGrants.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,11 @@ import { Route } from '@proteinjs/server-api';
13
13
  * Domain rail: `?email` must share `DEV_AUTO_LOGIN_EMAIL`'s domain — even a dev server must not
14
14
  * mint sessions (much less accounts) for arbitrary domains; anything else answers 400.
15
15
  *
16
+ * Shape rail: `?email` must be a well-formed address (the house `emailRegex`). The domain rail
17
+ * alone let `?email=brent+lane-a@…` through when the `+` was left unencoded — a query-string `+`
18
+ * decodes to a SPACE, so the route minted a stray `brent lane-a@…` account. The 400 names the
19
+ * remedy (`%2B`) because plus-addressing is the fan-out convention this door exists for.
20
+ *
16
21
  * A missing account is created through the normal signup creation path (`Signup.createAccount`)
17
22
  * as a normal test user — password `test`, matching the seeded test-account convention, so
18
23
  * interactive login works for the same identity. Composes with userCache's missing-account→guest
@@ -1 +1 @@
1
- {"version":3,"file":"devLogin.d.ts","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAW9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAuCtB,CAAC"}
1
+ {"version":3,"file":"devLogin.d.ts","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAY9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAgDtB,CAAC"}
@@ -38,6 +38,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.devLogin = void 0;
40
40
  var logger_1 = require("@proteinjs/logger");
41
+ var util_1 = require("@proteinjs/util");
41
42
  var establishSession_1 = require("../authentication/establishSession");
42
43
  var Signup_1 = require("../services/Signup");
43
44
  var logger = new logger_1.Logger({ name: 'devLogin' });
@@ -58,6 +59,11 @@ var emailDomain = function (address) { return address.slice(address.lastIndexOf(
58
59
  * Domain rail: `?email` must share `DEV_AUTO_LOGIN_EMAIL`'s domain — even a dev server must not
59
60
  * mint sessions (much less accounts) for arbitrary domains; anything else answers 400.
60
61
  *
62
+ * Shape rail: `?email` must be a well-formed address (the house `emailRegex`). The domain rail
63
+ * alone let `?email=brent+lane-a@…` through when the `+` was left unencoded — a query-string `+`
64
+ * decodes to a SPACE, so the route minted a stray `brent lane-a@…` account. The 400 names the
65
+ * remedy (`%2B`) because plus-addressing is the fan-out convention this door exists for.
66
+ *
61
67
  * A missing account is created through the normal signup creation path (`Signup.createAccount`)
62
68
  * as a normal test user — password `test`, matching the seeded test-account convention, so
63
69
  * interactive login works for the same identity. Composes with userCache's missing-account→guest
@@ -86,6 +92,13 @@ exports.devLogin = {
86
92
  response.status(400).send("/dev/login only accepts accounts on the @".concat(emailDomain(envEmail), " domain"));
87
93
  return [2 /*return*/];
88
94
  }
95
+ if (!util_1.emailRegex.test(requested)) {
96
+ response
97
+ .status(400)
98
+ .send("/dev/login: \"".concat(requested, "\" is not a valid email address \u2014 an unencoded \"+\" in the query ") +
99
+ "decodes to a space; write it as %2B (e.g. ?email=name%2Blane@".concat(emailDomain(envEmail), ")"));
100
+ return [2 /*return*/];
101
+ }
89
102
  email = requested;
90
103
  }
91
104
  email = email.toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAC3C,uEAAsE;AACtE,6CAA4C;AAE5C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEhD;kFACkF;AAClF,IAAM,WAAW,GAAG,UAAC,OAAe,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAzD,CAAyD,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,QAAQ,GAAU;IAC7B,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,QAAQ,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBACjE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,QAAQ,EAAE;wBACzC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBAC5B,sBAAO;qBACR;oBAEG,KAAK,GAAG,QAAQ,CAAC;oBACf,UAAU,GAAG,MAAA,OAAO,CAAC,KAAK,0CAAE,KAAK,CAAC;oBACxC,IAAI,UAAU,KAAK,SAAS,EAAE;wBACtB,SAAS,GAAG,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC1E,IAAI,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,EAAE;4BACpD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mDAA4C,WAAW,CAAC,QAAQ,CAAC,YAAS,CAAC,CAAC;4BACtG,sBAAO;yBACR;wBACD,KAAK,GAAG,SAAS,CAAC;qBACnB;oBACD,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;oBAEX,qBAAM,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC;4BAChD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;4BACxC,KAAK,OAAA;4BACL,QAAQ,EAAE,MAAM;4BAChB,aAAa,EAAE,KAAK;4BACpB,SAAS,EAAE,IAAI;yBAChB,CAAC,EAAA;;oBANI,QAAQ,GAAG,SAMf;oBACF,IAAI,QAAQ,KAAK,SAAS,EAAE;wBAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,6CAA6C,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;qBACzF;oBAED,2FAA2F;oBAC3F,8FAA8F;oBAC9F,qBAAM,IAAA,mCAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,EAAA;;oBAFtC,2FAA2F;oBAC3F,8FAA8F;oBAC9F,SAAsC,CAAC;oBACvC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;oBAC/E,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;;;;SACxB;CACF,CAAC"}
1
+ {"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAC3C,wCAA6C;AAC7C,uEAAsE;AACtE,6CAA4C;AAE5C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEhD;kFACkF;AAClF,IAAM,WAAW,GAAG,UAAC,OAAe,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAzD,CAAyD,CAAC;AAEnG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACU,QAAA,QAAQ,GAAU;IAC7B,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,QAAQ,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBACjE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,QAAQ,EAAE;wBACzC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBAC5B,sBAAO;qBACR;oBAEG,KAAK,GAAG,QAAQ,CAAC;oBACf,UAAU,GAAG,MAAA,OAAO,CAAC,KAAK,0CAAE,KAAK,CAAC;oBACxC,IAAI,UAAU,KAAK,SAAS,EAAE;wBACtB,SAAS,GAAG,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC1E,IAAI,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW,CAAC,QAAQ,CAAC,EAAE;4BACpD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mDAA4C,WAAW,CAAC,QAAQ,CAAC,YAAS,CAAC,CAAC;4BACtG,sBAAO;yBACR;wBACD,IAAI,CAAC,iBAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;4BAC/B,QAAQ;iCACL,MAAM,CAAC,GAAG,CAAC;iCACX,IAAI,CACH,wBAAgB,SAAS,4EAAiE;gCACxF,uEAAgE,WAAW,CAAC,QAAQ,CAAC,MAAG,CAC3F,CAAC;4BACJ,sBAAO;yBACR;wBACD,KAAK,GAAG,SAAS,CAAC;qBACnB;oBACD,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;oBAEX,qBAAM,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC;4BAChD,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;4BACxC,KAAK,OAAA;4BACL,QAAQ,EAAE,MAAM;4BAChB,aAAa,EAAE,KAAK;4BACpB,SAAS,EAAE,IAAI;yBAChB,CAAC,EAAA;;oBANI,QAAQ,GAAG,SAMf;oBACF,IAAI,QAAQ,KAAK,SAAS,EAAE;wBAC1B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,6CAA6C,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;qBACzF;oBAED,2FAA2F;oBAC3F,8FAA8F;oBAC9F,qBAAM,IAAA,mCAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,EAAA;;oBAFtC,2FAA2F;oBAC3F,8FAA8F;oBAC9F,SAAsC,CAAC;oBACvC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;oBAC/E,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;;;;SACxB;CACF,CAAC"}
@@ -5,6 +5,8 @@ import { Service } from '@proteinjs/service';
5
5
  * record writes cannot touch it). Grants and revokes are validated against the roles catalog and
6
6
  * audited: the role update and its `role_grant_event` row (actor, target, role, action; `created`
7
7
  * is the timestamp) commit in one transaction, so the trail cannot diverge from the grants.
8
+ *
9
+ * Break-glass roles are never granted here — see `changeRole`; revoking one stays allowed.
8
10
  */
9
11
  export declare class Roles implements RolesService {
10
12
  serviceMetadata: Service['serviceMetadata'];
@@ -1 +1 @@
1
- {"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAoD,MAAM,iBAAiB,CAAC;AAEjG,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,YAAY;IACjC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAIhD;IAEI,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI/C,UAAU;CA4CzB"}
1
+ {"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA8D,MAAM,iBAAiB,CAAC;AAE3G,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;;;;;;GAOG;AACH,qBAAa,KAAM,YAAW,YAAY;IACjC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAIhD;IAEI,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI/C,UAAU;CAoEzB"}
@@ -54,6 +54,8 @@ var logger_1 = require("@proteinjs/logger");
54
54
  * record writes cannot touch it). Grants and revokes are validated against the roles catalog and
55
55
  * audited: the role update and its `role_grant_event` row (actor, target, role, action; `created`
56
56
  * is the timestamp) commit in one transaction, so the trail cannot diverge from the grants.
57
+ *
58
+ * Break-glass roles are never granted here — see `changeRole`; revoking one stays allowed.
57
59
  */
58
60
  var Roles = /** @class */ (function () {
59
61
  function Roles() {
@@ -90,15 +92,33 @@ var Roles = /** @class */ (function () {
90
92
  Roles.prototype.changeRole = function (userId, role, action) {
91
93
  var _a;
92
94
  return __awaiter(this, void 0, void 0, function () {
93
- var logger, db, user, roles, newRoles, actor;
95
+ var logger, entry, db, user, roles, newRoles, actor;
94
96
  var _this = this;
95
97
  return __generator(this, function (_b) {
96
98
  switch (_b.label) {
97
99
  case 0:
98
100
  logger = new logger_1.Logger({ name: "Roles.".concat(action, "Role") });
99
- if (!user_1.RolesCatalog.isKnownRole(role)) {
101
+ entry = user_1.RolesCatalog.getEntry(role);
102
+ if (!entry) {
100
103
  throw new Error("'".concat(role, "' is not a known role. Pick one from the roles catalog."));
101
104
  }
105
+ // Break-glass passes every permission check, so no permission-mapped role — including
106
+ // 'roles' — may mint it: the only path to break-glass is a manual UPDATE on the user row
107
+ // in Spanner Studio, by a human, on purpose. Revoke stays open: de-escalation toward
108
+ // "held by nobody day-to-day" should ride the audited path, not require database access.
109
+ if (entry.breakGlass && action === 'grant') {
110
+ throw new Error("'".concat(role, "' is a break-glass role \u2014 this service refuses to grant it. The only path to ") +
111
+ "break-glass is a manual UPDATE on the user row in Spanner Studio. (Revoking it here " +
112
+ "stays allowed.)");
113
+ }
114
+ // Admin-grant-only roles (catalog `adminGrantOnly`) exceed the people-management trust the
115
+ // 'roles' permission carries — only an admin may hand them out. Server-side and fail-closed:
116
+ // the service door admits 'roles' holders, so this check is what keeps a user-admin from
117
+ // granting such a role. Revoke stays open — the break-glass de-escalation precedent above.
118
+ if (entry.adminGrantOnly && action === 'grant' && !user_1.UserAuth.hasRole('admin')) {
119
+ throw new Error("'".concat(role, "' can only be granted by an admin \u2014 the 'roles' grant does not cover it. ") +
120
+ "(Revoking it here stays allowed.)");
121
+ }
102
122
  db = (0, db_1.getDbAsSystem)();
103
123
  return [4 /*yield*/, db.get(user_1.tables.User, { id: userId })];
104
124
  case 1:
@@ -1 +1 @@
1
- {"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"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"}
@@ -215,6 +215,47 @@ describe('devLogin route', function () {
215
215
  }
216
216
  });
217
217
  }); });
218
+ it('rejects a malformed same-domain ?email with 400 — no session, no stray account', function () { return __awaiter(void 0, void 0, void 0, function () {
219
+ var malformed, outcome, _a;
220
+ return __generator(this, function (_b) {
221
+ switch (_b.label) {
222
+ case 0:
223
+ malformed = 'brent shareproof-a@test.local';
224
+ return [4 /*yield*/, invokeDevLogin({ email: malformed })];
225
+ case 1:
226
+ outcome = _b.sent();
227
+ expect(outcome.status).toBe(400);
228
+ expect(String(outcome.body)).toMatch(/not a valid email/i);
229
+ expect(String(outcome.body)).toMatch(/%2B/); // the remedy: percent-encode the `+`
230
+ expect(outcome.loggedInAs).toBeUndefined();
231
+ expect(outcome.sessionSaved).toBe(false);
232
+ expect(outcome.redirect).toBeUndefined();
233
+ _a = expect;
234
+ return [4 /*yield*/, getUserRow(malformed)];
235
+ case 2:
236
+ _a.apply(void 0, [_b.sent()]).toBeUndefined();
237
+ return [2 /*return*/];
238
+ }
239
+ });
240
+ }); });
241
+ it('still accepts a plus-addressed ?email once it is encoded (the fan-out convention)', function () { return __awaiter(void 0, void 0, void 0, function () {
242
+ var outcome, _a;
243
+ return __generator(this, function (_b) {
244
+ switch (_b.label) {
245
+ case 0: return [4 /*yield*/, invokeDevLogin({ email: 'agent6+lane-a@test.local' })];
246
+ case 1:
247
+ outcome = _b.sent();
248
+ expect(outcome.loggedInAs).toBe('agent6+lane-a@test.local');
249
+ expect(outcome.sessionSaved).toBe(true);
250
+ expect(outcome.redirect).toBe('/');
251
+ _a = expect;
252
+ return [4 /*yield*/, getUserRow('agent6+lane-a@test.local')];
253
+ case 2:
254
+ _a.apply(void 0, [_b.sent()]).toBeDefined();
255
+ return [2 /*return*/];
256
+ }
257
+ });
258
+ }); });
218
259
  it('404s when DEVELOPMENT is unset, even with a ?email', function () { return __awaiter(void 0, void 0, void 0, function () {
219
260
  var outcome, _a;
220
261
  return __generator(this, function (_b) {
@@ -1 +1 @@
1
- {"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA8C;AAC9C,wCAAyC;AACzC,uEAAsE;AACtE,mDAAkD;AAClD,mEAAiE;AACjE,yEAAwE;AAExE,IAAM,OAAO,GAAG,IAAI,qDAAyB,EAAE,CAAC;AAEhD;;;;;;;;GAQG;AAEH,IAAM,SAAS,GAAG,gBAAgB,CAAC;AAWnC,IAAM,cAAc,GAAG,UAAO,KAA+B;;;;;oBAI/B,qBAAM,IAAA,8CAAqB,EAAC,EAAE,KAAK,OAAA,EAAE,CAAC,EAAA;;gBAA5D,KAAsB,SAAsC,EAA1D,OAAO,aAAA,EAAE,MAAM,YAAA;gBACjB,OAAO,GAAiB,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;gBAC3E,QAAQ,GAAG;oBACf,MAAM,YAAC,IAAY;wBACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;wBACtB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,IAAI,YAAC,IAAc;wBACjB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBACtB,CAAC;oBACD,QAAQ,YAAC,IAAY;wBACnB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;oBAC1B,CAAC;iBACF,CAAC;gBACF,qBAAM,mBAAQ,CAAC,SAAS,CAAC,OAAgB,EAAE,QAAiB,CAAC,EAAA;;gBAA7D,SAA6D,CAAC;gBAC9D,OAAO,CAAC,UAAU,GAAG,MAAA,OAAO,CAAC,OAAO,CAAC,QAAQ,0CAAE,IAAI,CAAC;gBACpD,OAAO,CAAC,kBAAkB,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;gBAC3D,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC/C,sBAAO,OAAO,EAAC;;;KAChB,CAAC;AAEF,IAAM,UAAU,GAAG,UAAO,KAAa;;gBAAK,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,OAAA,EAAE,CAAC,EAAA;gBAAjD,sBAAA,SAAiD,EAAA;;SAAA,CAAC;AAE9F,QAAQ,CAAC,gBAAgB,EAAE;IACzB,IAAM,WAAW,GAAG;QAClB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;QACpC,oBAAoB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;KACvD,CAAC;IAEF,SAAS,CAAC;;;wBACR,qBAAM,OAAO,CAAC,SAAS,EAAE,EAAA;;oBAAzB,SAAyB,CAAC;;;;SAC3B,CAAC,CAAC;IAEH,QAAQ,CAAC;;;wBACP,qBAAM,OAAO,CAAC,QAAQ,EAAE,EAAA;;oBAAxB,SAAwB,CAAC;;;;SAC1B,CAAC,CAAC;IAEH,UAAU,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,KAA2B,UAA2B,EAA3B,KAAA,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAA3B,cAA2B,EAA3B,IAA2B,EAAE;YAA7C,IAAA,WAAY,EAAX,GAAG,QAAA,EAAE,KAAK,QAAA;YACpB,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aACzB;iBAAM;gBACL,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aAC1B;SACF;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE;;;;wBACvF,qBAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAA;;oBAAnE,SAAmE,CAAC;oBAEpD,qBAAM,cAAc,EAAE,EAAA;;oBAAhC,OAAO,GAAG,SAAsB;oBAEtC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC3C,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0CAA0C;oBACzF,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACxC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACnC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;;;;SACxC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE;;;;wBACnE,qBAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAA3E,SAA2E,CAAC;oBAE5D,qBAAM,cAAc,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAA9D,OAAO,GAAG,SAAoD;oBAEpE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;oBACrD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACxC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;;;SACpC,CAAC,CAAC;IAEH,EAAE,CAAC,6FAA6F,EAAE;;;;;oBAChG,KAAA,MAAM,CAAA;oBAAC,qBAAM,UAAU,CAAC,mBAAmB,CAAC,EAAA;;oBAA5C,kBAAO,SAAqC,EAAC,CAAC,aAAa,EAAE,CAAC;oBAE9C,qBAAM,cAAc,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAA9D,OAAO,GAAG,SAAoD;oBAEpE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;oBACrD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACxC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAInB,qBAAM,UAAU,CAAC,mBAAmB,CAAC,EAAA;;oBAA/C,OAAO,GAAG,SAAqC;oBACrD,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;oBAC9B,MAAM,CAAC,OAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9D,KAAA,MAAM,CAAA;oBAAC,qBAAM,IAAI,+BAAc,EAAE,CAAC,MAAM,CAAC,OAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAA;;oBAAnE,kBAAO,SAA4D,EAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAChF,MAAM,CAAC,OAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACnC,MAAM,CAAC,OAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;;;;SACpC,CAAC,CAAC;IAEH,EAAE,CAAC,4FAA4F,EAAE;;;;wBAC/E,qBAAM,cAAc,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,EAAA;;oBAAlE,OAAO,GAAG,SAAwD;oBAExE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAC;oBAC3C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACzC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;oBACzC,KAAA,MAAM,CAAA;oBAAC,qBAAM,UAAU,CAAC,uBAAuB,CAAC,EAAA;;oBAAhD,kBAAO,SAAyC,EAAC,CAAC,aAAa,EAAE,CAAC;;;;SACnE,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE;;;;;oBACvD,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;oBAEf,qBAAM,cAAc,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAA9D,OAAO,GAAG,SAAoD;oBAEpE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAC;oBAC3C,KAAA,MAAM,CAAA;oBAAC,qBAAM,UAAU,CAAC,mBAAmB,CAAC,EAAA;;oBAA5C,kBAAO,SAAqC,EAAC,CAAC,aAAa,EAAE,CAAC;;;;SAC/D,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE;;;;;oBAChE,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;oBAExB,qBAAM,cAAc,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAA9D,OAAO,GAAG,SAAoD;oBAEpE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACjC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAC;oBAC3C,KAAA,MAAM,CAAA;oBAAC,qBAAM,UAAU,CAAC,mBAAmB,CAAC,EAAA;;oBAA5C,kBAAO,SAAqC,EAAC,CAAC,aAAa,EAAE,CAAC;;;;SAC/D,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":"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"}