@proteinjs/user-server 1.22.1 → 1.22.3

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 (152) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/generated/index.js +1 -1
  3. package/dist/generated/index.js.map +1 -1
  4. package/dist/index.d.ts +3 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +9 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/authentication/PasswordHasher.d.ts +9 -0
  9. package/dist/src/authentication/PasswordHasher.d.ts.map +1 -1
  10. package/dist/src/authentication/PasswordHasher.js +25 -0
  11. package/dist/src/authentication/PasswordHasher.js.map +1 -1
  12. package/dist/src/authentication/SocketIOSessionWatcher.d.ts +5 -0
  13. package/dist/src/authentication/SocketIOSessionWatcher.d.ts.map +1 -1
  14. package/dist/src/authentication/SocketIOSessionWatcher.js +13 -2
  15. package/dist/src/authentication/SocketIOSessionWatcher.js.map +1 -1
  16. package/dist/src/authentication/UserStatusTableWatcher.d.ts.map +1 -1
  17. package/dist/src/authentication/UserStatusTableWatcher.js +2 -1
  18. package/dist/src/authentication/UserStatusTableWatcher.js.map +1 -1
  19. package/dist/src/authentication/authenticate.d.ts +15 -0
  20. package/dist/src/authentication/authenticate.d.ts.map +1 -1
  21. package/dist/src/authentication/authenticate.js +55 -20
  22. package/dist/src/authentication/authenticate.js.map +1 -1
  23. package/dist/src/authorization/userCache.d.ts.map +1 -1
  24. package/dist/src/authorization/userCache.js +3 -2
  25. package/dist/src/authorization/userCache.js.map +1 -1
  26. package/dist/src/routes/devLogin.d.ts.map +1 -1
  27. package/dist/src/routes/devLogin.js +29 -14
  28. package/dist/src/routes/devLogin.js.map +1 -1
  29. package/dist/src/routes/executePasswordReset.d.ts +4 -0
  30. package/dist/src/routes/executePasswordReset.d.ts.map +1 -1
  31. package/dist/src/routes/executePasswordReset.js +12 -4
  32. package/dist/src/routes/executePasswordReset.js.map +1 -1
  33. package/dist/src/routes/initiatePasswordReset.d.ts +7 -0
  34. package/dist/src/routes/initiatePasswordReset.d.ts.map +1 -1
  35. package/dist/src/routes/initiatePasswordReset.js +28 -10
  36. package/dist/src/routes/initiatePasswordReset.js.map +1 -1
  37. package/dist/src/routes/login.d.ts +8 -0
  38. package/dist/src/routes/login.d.ts.map +1 -1
  39. package/dist/src/routes/login.js +63 -22
  40. package/dist/src/routes/login.js.map +1 -1
  41. package/dist/src/routes/signup.d.ts.map +1 -1
  42. package/dist/src/routes/signup.js +5 -2
  43. package/dist/src/routes/signup.js.map +1 -1
  44. package/dist/src/routes/validateResetPasswordToken.d.ts.map +1 -1
  45. package/dist/src/routes/validateResetPasswordToken.js +5 -1
  46. package/dist/src/routes/validateResetPasswordToken.js.map +1 -1
  47. package/dist/src/services/MachineCredentials.d.ts +10 -1
  48. package/dist/src/services/MachineCredentials.d.ts.map +1 -1
  49. package/dist/src/services/MachineCredentials.js +46 -15
  50. package/dist/src/services/MachineCredentials.js.map +1 -1
  51. package/dist/src/services/Roles.d.ts.map +1 -1
  52. package/dist/src/services/Roles.js +6 -2
  53. package/dist/src/services/Roles.js.map +1 -1
  54. package/dist/src/services/Signup.d.ts +5 -0
  55. package/dist/src/services/Signup.d.ts.map +1 -1
  56. package/dist/src/services/Signup.js +28 -6
  57. package/dist/src/services/Signup.js.map +1 -1
  58. package/dist/src/throttle/ClientAddress.d.ts +35 -0
  59. package/dist/src/throttle/ClientAddress.d.ts.map +1 -0
  60. package/dist/src/throttle/ClientAddress.js +48 -0
  61. package/dist/src/throttle/ClientAddress.js.map +1 -0
  62. package/dist/src/throttle/PasswordResetThrottle.d.ts +39 -0
  63. package/dist/src/throttle/PasswordResetThrottle.d.ts.map +1 -0
  64. package/dist/src/throttle/PasswordResetThrottle.js +59 -0
  65. package/dist/src/throttle/PasswordResetThrottle.js.map +1 -0
  66. package/dist/src/throttle/RequestDigests.d.ts +42 -0
  67. package/dist/src/throttle/RequestDigests.d.ts.map +1 -0
  68. package/dist/src/throttle/RequestDigests.js +96 -0
  69. package/dist/src/throttle/RequestDigests.js.map +1 -0
  70. package/dist/src/throttle/SignInThrottle.d.ts +67 -0
  71. package/dist/src/throttle/SignInThrottle.d.ts.map +1 -0
  72. package/dist/src/throttle/SignInThrottle.js +91 -0
  73. package/dist/src/throttle/SignInThrottle.js.map +1 -0
  74. package/dist/src/throttle/SlidingWindow.d.ts +51 -0
  75. package/dist/src/throttle/SlidingWindow.d.ts.map +1 -0
  76. package/dist/src/throttle/SlidingWindow.js +85 -0
  77. package/dist/src/throttle/SlidingWindow.js.map +1 -0
  78. package/dist/test/ClientAddress.test.d.ts +2 -0
  79. package/dist/test/ClientAddress.test.d.ts.map +1 -0
  80. package/dist/test/ClientAddress.test.js +51 -0
  81. package/dist/test/ClientAddress.test.js.map +1 -0
  82. package/dist/test/DevLogin.test.js +68 -0
  83. package/dist/test/DevLogin.test.js.map +1 -1
  84. package/dist/test/InitiatePasswordReset.test.js +373 -5
  85. package/dist/test/InitiatePasswordReset.test.js.map +1 -1
  86. package/dist/test/LogCapture.d.ts +10 -0
  87. package/dist/test/LogCapture.d.ts.map +1 -1
  88. package/dist/test/LogCapture.js +19 -0
  89. package/dist/test/LogCapture.js.map +1 -1
  90. package/dist/test/LogCapture.test.d.ts +2 -0
  91. package/dist/test/LogCapture.test.d.ts.map +1 -0
  92. package/dist/test/LogCapture.test.js +86 -0
  93. package/dist/test/LogCapture.test.js.map +1 -0
  94. package/dist/test/LoginThrottle.integration.test.d.ts +2 -0
  95. package/dist/test/LoginThrottle.integration.test.d.ts.map +1 -0
  96. package/dist/test/LoginThrottle.integration.test.js +616 -0
  97. package/dist/test/LoginThrottle.integration.test.js.map +1 -0
  98. package/dist/test/MachineAccounts.integration.test.js +156 -28
  99. package/dist/test/MachineAccounts.integration.test.js.map +1 -1
  100. package/dist/test/NoAddressesInLogs.integration.test.d.ts +2 -0
  101. package/dist/test/NoAddressesInLogs.integration.test.d.ts.map +1 -0
  102. package/dist/test/NoAddressesInLogs.integration.test.js +717 -0
  103. package/dist/test/NoAddressesInLogs.integration.test.js.map +1 -0
  104. package/dist/test/RequestDigests.test.d.ts +2 -0
  105. package/dist/test/RequestDigests.test.d.ts.map +1 -0
  106. package/dist/test/RequestDigests.test.js +73 -0
  107. package/dist/test/RequestDigests.test.js.map +1 -0
  108. package/dist/test/SignupRoute.test.js +80 -1
  109. package/dist/test/SignupRoute.test.js.map +1 -1
  110. package/dist/test/SlidingWindow.test.d.ts +2 -0
  111. package/dist/test/SlidingWindow.test.d.ts.map +1 -0
  112. package/dist/test/SlidingWindow.test.js +72 -0
  113. package/dist/test/SlidingWindow.test.js.map +1 -0
  114. package/dist/test/SocketIOSessionWatcher.test.d.ts +2 -0
  115. package/dist/test/SocketIOSessionWatcher.test.d.ts.map +1 -0
  116. package/dist/test/SocketIOSessionWatcher.test.js +144 -0
  117. package/dist/test/SocketIOSessionWatcher.test.js.map +1 -0
  118. package/generated/index.ts +1 -1
  119. package/index.ts +5 -0
  120. package/package.json +6 -5
  121. package/src/authentication/PasswordHasher.ts +18 -1
  122. package/src/authentication/SocketIOSessionWatcher.ts +13 -1
  123. package/src/authentication/UserStatusTableWatcher.ts +2 -1
  124. package/src/authentication/authenticate.ts +36 -9
  125. package/src/authorization/userCache.ts +3 -2
  126. package/src/routes/devLogin.ts +22 -10
  127. package/src/routes/executePasswordReset.ts +11 -3
  128. package/src/routes/initiatePasswordReset.ts +29 -11
  129. package/src/routes/login.ts +39 -8
  130. package/src/routes/signup.ts +5 -2
  131. package/src/routes/validateResetPasswordToken.ts +5 -1
  132. package/src/services/MachineCredentials.ts +44 -9
  133. package/src/services/Roles.ts +6 -2
  134. package/src/services/Signup.ts +30 -4
  135. package/src/throttle/ClientAddress.ts +47 -0
  136. package/src/throttle/PasswordResetThrottle.ts +62 -0
  137. package/src/throttle/RequestDigests.ts +97 -0
  138. package/src/throttle/SignInThrottle.ts +98 -0
  139. package/src/throttle/SlidingWindow.ts +90 -0
  140. package/test/ClientAddress.test.ts +54 -0
  141. package/test/DevLogin.test.ts +35 -1
  142. package/test/InitiatePasswordReset.test.ts +212 -6
  143. package/test/LogCapture.test.ts +29 -0
  144. package/test/LogCapture.ts +16 -0
  145. package/test/LoginThrottle.integration.test.ts +339 -0
  146. package/test/MachineAccounts.integration.test.ts +97 -22
  147. package/test/NoAddressesInLogs.integration.test.ts +409 -0
  148. package/test/RequestDigests.test.ts +81 -0
  149. package/test/SignupRoute.test.ts +54 -1
  150. package/test/SlidingWindow.test.ts +85 -0
  151. package/test/SocketIOSessionWatcher.test.ts +86 -0
  152. package/test/setup.js +2 -0
@@ -56,6 +56,7 @@ var user_1 = require("@proteinjs/user");
56
56
  var moment_1 = __importDefault(require("moment"));
57
57
  var crypto_js_1 = require("crypto-js");
58
58
  var logger_1 = require("@proteinjs/logger");
59
+ var util_node_1 = require("@proteinjs/util-node");
59
60
  var email_server_1 = require("@proteinjs/email-server");
60
61
  var reflection_1 = require("@proteinjs/reflection");
61
62
  var PasswordHasher_1 = require("../authentication/PasswordHasher");
@@ -135,7 +136,10 @@ var Signup = /** @class */ (function () {
135
136
  case 4:
136
137
  creation = _g.sent();
137
138
  if (!(creation === 'exists')) return [3 /*break*/, 7];
138
- logger.error({ message: "User with this email already exists", obj: { email: email } });
139
+ logger.error({
140
+ message: "User with this email already exists",
141
+ obj: { account: new util_node_1.RequestDigests().account(email) },
142
+ });
139
143
  if (!config.getExistingUserEmailContent) return [3 /*break*/, 6];
140
144
  _e = config.getExistingUserEmailContent(), text_1 = _e.text, html_1 = _e.html;
141
145
  return [4 /*yield*/, emailSender.sendEmail(__assign({ to: email, subject: config.existingUserSubject || ((_c = config.options) === null || _c === void 0 ? void 0 : _c.subject) || 'Account already exists', text: text_1, html: html_1 }, config.options))];
@@ -148,7 +152,7 @@ var Signup = /** @class */ (function () {
148
152
  return [4 /*yield*/, emailSender.sendEmail(__assign({ to: email, subject: config.newUserSubject || ((_d = config.options) === null || _d === void 0 ? void 0 : _d.subject) || 'Welcome!', text: text, html: html }, config.options))];
149
153
  case 8:
150
154
  _g.sent();
151
- logger.info({ message: "Created user", obj: { email: email } });
155
+ logger.info({ message: "Created user", obj: { account: new util_node_1.RequestDigests().account(email) } });
152
156
  return [2 /*return*/, { outcome: 'created', email: email }];
153
157
  }
154
158
  });
@@ -156,7 +160,7 @@ var Signup = /** @class */ (function () {
156
160
  };
157
161
  Signup.prototype.sendInvite = function (email) {
158
162
  return __awaiter(this, void 0, void 0, function () {
159
- var logger, caseInsensitiveEmail, db, userRecord, config, _a, token, tokenExpiresAt, invite, userId, error_1;
163
+ var logger, caseInsensitiveEmail, db, userRecord, config, _a, token, tokenExpiresAt, invite, userId, error_1, digests;
160
164
  return __generator(this, function (_b) {
161
165
  switch (_b.label) {
162
166
  case 0:
@@ -200,7 +204,12 @@ var Signup = /** @class */ (function () {
200
204
  return [2 /*return*/, { sent: true }];
201
205
  case 9:
202
206
  error_1 = _b.sent();
203
- logger.error({ message: 'Error sending invite', obj: { email: caseInsensitiveEmail }, error: error_1 });
207
+ digests = new util_node_1.RequestDigests();
208
+ logger.error({
209
+ message: 'Error sending invite',
210
+ obj: { invitee: digests.address(caseInsensitiveEmail) },
211
+ error: digests.redactError(error_1),
212
+ });
204
213
  return [2 /*return*/, {
205
214
  sent: false,
206
215
  error: 'Error occurred.',
@@ -219,7 +228,7 @@ var Signup = /** @class */ (function () {
219
228
  */
220
229
  Signup.prototype.resendInvite = function (email) {
221
230
  return __awaiter(this, void 0, void 0, function () {
222
- var logger, caseInsensitiveEmail, db, userRecord, invite, config, _a, token, tokenExpiresAt, error_2;
231
+ var logger, caseInsensitiveEmail, db, userRecord, invite, config, _a, token, tokenExpiresAt, error_2, digests;
223
232
  return __generator(this, function (_b) {
224
233
  switch (_b.label) {
225
234
  case 0:
@@ -252,7 +261,12 @@ var Signup = /** @class */ (function () {
252
261
  return [2 /*return*/, { sent: true }];
253
262
  case 6:
254
263
  error_2 = _b.sent();
255
- logger.error({ message: 'Error re-sending invite', obj: { email: caseInsensitiveEmail }, error: error_2 });
264
+ digests = new util_node_1.RequestDigests();
265
+ logger.error({
266
+ message: 'Error re-sending invite',
267
+ obj: { invitee: digests.address(caseInsensitiveEmail) },
268
+ error: digests.redactError(error_2),
269
+ });
256
270
  return [2 /*return*/, {
257
271
  sent: false,
258
272
  error: 'Error occurred.',
@@ -346,6 +360,11 @@ var Signup = /** @class */ (function () {
346
360
  * (`devLogin`, which auto-creates missing same-domain test accounts). Not exposed as an RPC:
347
361
  * the service surface is the `SignupService` INTERFACE (ServiceRouter walks its declared
348
362
  * methods), so extra class methods stay server-internal.
363
+ *
364
+ * An address a `MachineAccount` declaration owns is never registered, whatever its row state:
365
+ * a person's row under it would make the boot sync refuse the declaration (it never takes over
366
+ * a row it does not own), so the address is refused here in plain words — the declared machine
367
+ * accounts of this build are the list, nothing else.
349
368
  */
350
369
  Signup.prototype.createAccount = function (account) {
351
370
  return __awaiter(this, void 0, void 0, function () {
@@ -356,6 +375,9 @@ var Signup = /** @class */ (function () {
356
375
  case 0:
357
376
  db = (0, db_1.getDbAsSystem)();
358
377
  email = account.email.toLowerCase();
378
+ if ((0, user_1.getMachineAccounts)().some(function (machineAccount) { return machineAccount.email === email; })) {
379
+ throw new Error("This address can't be registered.");
380
+ }
359
381
  return [4 /*yield*/, db.get(user_1.tables.User, { email: email })];
360
382
  case 1:
361
383
  existingUser = _e.sent();
@@ -1 +1 @@
1
- {"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /** The request fields the read needs — an express request has all of them. */
2
+ type ClientRequest = {
3
+ app?: {
4
+ get?: (setting: string) => unknown;
5
+ };
6
+ headers?: Record<string, string | string[] | undefined>;
7
+ socket?: {
8
+ remoteAddress?: string;
9
+ };
10
+ };
11
+ /**
12
+ * The client's address, as a throttle should key on it.
13
+ *
14
+ * Behind Google's external Application Load Balancer the `X-Forwarded-For` header ENDS with the
15
+ * two entries the balancer appends — `<client-ip>,<load-balancer-ip>` — and everything before
16
+ * them is whatever the client itself sent. So the client is the second entry from the right:
17
+ * - never the LAST entry: that is the balancer's own forwarding-rule address, the same for every
18
+ * visitor. It is what express's `request.ip` resolves to under the server's `trust proxy 1`
19
+ * (one trusted hop: the Google front end that opened the connection), so a throttle keyed on
20
+ * `request.ip` there is one bucket for the whole world;
21
+ * - never the FIRST entry: a client can send its own header, and the balancer keeps it.
22
+ *
23
+ * Only when the server trusts a proxy (the deployed shape; `trust proxy` is unset in
24
+ * development) is the header read at all. A request that did not come through the balancer —
25
+ * no appended pair: an in-cluster call, a probe — and every request in development key on the
26
+ * connection's own address.
27
+ */
28
+ export declare class ClientAddress {
29
+ /** How many entries the load balancer appends to the header: the client, then itself. */
30
+ private static readonly BALANCER_APPENDED_ENTRIES;
31
+ of(request: ClientRequest): string;
32
+ private forwardedFor;
33
+ }
34
+ export {};
35
+ //# sourceMappingURL=ClientAddress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientAddress.d.ts","sourceRoot":"","sources":["../../../src/throttle/ClientAddress.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,KAAK,aAAa,GAAG;IACnB,GAAG,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAA;KAAE,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACxB,yFAAyF;IACzF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAK;IAEtD,EAAE,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM;IAUlC,OAAO,CAAC,YAAY;CAQrB"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientAddress = void 0;
4
+ /**
5
+ * The client's address, as a throttle should key on it.
6
+ *
7
+ * Behind Google's external Application Load Balancer the `X-Forwarded-For` header ENDS with the
8
+ * two entries the balancer appends — `<client-ip>,<load-balancer-ip>` — and everything before
9
+ * them is whatever the client itself sent. So the client is the second entry from the right:
10
+ * - never the LAST entry: that is the balancer's own forwarding-rule address, the same for every
11
+ * visitor. It is what express's `request.ip` resolves to under the server's `trust proxy 1`
12
+ * (one trusted hop: the Google front end that opened the connection), so a throttle keyed on
13
+ * `request.ip` there is one bucket for the whole world;
14
+ * - never the FIRST entry: a client can send its own header, and the balancer keeps it.
15
+ *
16
+ * Only when the server trusts a proxy (the deployed shape; `trust proxy` is unset in
17
+ * development) is the header read at all. A request that did not come through the balancer —
18
+ * no appended pair: an in-cluster call, a probe — and every request in development key on the
19
+ * connection's own address.
20
+ */
21
+ var ClientAddress = /** @class */ (function () {
22
+ function ClientAddress() {
23
+ }
24
+ ClientAddress.prototype.of = function (request) {
25
+ var _a, _b, _c, _d;
26
+ if ((_b = (_a = request.app) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, 'trust proxy')) {
27
+ var entries = this.forwardedFor(request);
28
+ if (entries.length >= ClientAddress.BALANCER_APPENDED_ENTRIES) {
29
+ return entries[entries.length - ClientAddress.BALANCER_APPENDED_ENTRIES];
30
+ }
31
+ }
32
+ return (_d = (_c = request.socket) === null || _c === void 0 ? void 0 : _c.remoteAddress) !== null && _d !== void 0 ? _d : '';
33
+ };
34
+ ClientAddress.prototype.forwardedFor = function (request) {
35
+ var _a;
36
+ var header = (_a = request.headers) === null || _a === void 0 ? void 0 : _a['x-forwarded-for'];
37
+ var value = Array.isArray(header) ? header.join(',') : header !== null && header !== void 0 ? header : '';
38
+ return value
39
+ .split(',')
40
+ .map(function (entry) { return entry.trim(); })
41
+ .filter(function (entry) { return entry.length > 0; });
42
+ };
43
+ /** How many entries the load balancer appends to the header: the client, then itself. */
44
+ ClientAddress.BALANCER_APPENDED_ENTRIES = 2;
45
+ return ClientAddress;
46
+ }());
47
+ exports.ClientAddress = ClientAddress;
48
+ //# sourceMappingURL=ClientAddress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientAddress.js","sourceRoot":"","sources":["../../../src/throttle/ClientAddress.ts"],"names":[],"mappings":";;;AAOA;;;;;;;;;;;;;;;;GAgBG;AACH;IAAA;IAsBA,CAAC;IAlBC,0BAAE,GAAF,UAAG,OAAsB;;QACvB,IAAI,MAAA,MAAA,OAAO,CAAC,GAAG,0CAAE,GAAG,mDAAG,aAAa,CAAC,EAAE;YACrC,IAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,yBAAyB,EAAE;gBAC7D,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,aAAa,CAAC,yBAAyB,CAAC,CAAC;aAC1E;SACF;QACD,OAAO,MAAA,MAAA,OAAO,CAAC,MAAM,0CAAE,aAAa,mCAAI,EAAE,CAAC;IAC7C,CAAC;IAEO,oCAAY,GAApB,UAAqB,OAAsB;;QACzC,IAAM,MAAM,GAAG,MAAA,OAAO,CAAC,OAAO,0CAAG,iBAAiB,CAAC,CAAC;QACpD,IAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,CAAC;QACtE,OAAO,KAAK;aACT,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,IAAI,EAAE,EAAZ,CAAY,CAAC;aAC5B,MAAM,CAAC,UAAC,KAAK,IAAK,OAAA,KAAK,CAAC,MAAM,GAAG,CAAC,EAAhB,CAAgB,CAAC,CAAC;IACzC,CAAC;IApBD,yFAAyF;IACjE,uCAAyB,GAAG,CAAC,CAAC;IAoBxD,oBAAC;CAAA,AAtBD,IAsBC;AAtBY,sCAAa"}
@@ -0,0 +1,39 @@
1
+ import { ThrottleWindow } from './SignInThrottle';
2
+ /**
3
+ * The password-reset door's two windows (`POST /user/initiate-password-reset`), keyed by digests
4
+ * (`RequestDigests`), never by an address. Both count every request, whether or not the address
5
+ * has an account — a window that only counted real accounts would itself say which addresses
6
+ * have one. Past either window nothing is looked up, minted or mailed; the door's answer is the
7
+ * same sentence as always (see the route).
8
+ *
9
+ * These sit on top of the account row's own five-minute gap between links, which spans replicas
10
+ * (it is stored); the windows are in process memory (`SlidingWindow`): per replica. A
11
+ * deployment of three replicas behind a load balancer (up to ten under load) keeps three sets
12
+ * of windows, so its effective ceiling is ~3× the numbers below (up to ~10×) — for one address
13
+ * still at most one mail per five minutes. Friction, not the wall — a shared store is a
14
+ * separate step.
15
+ */
16
+ export declare class PasswordResetThrottle {
17
+ /**
18
+ * Per client: 10 requests an hour. Someone asking for their own address again, or a household
19
+ * asking for a few addresses, passes; a script sweeping addresses stops at ten.
20
+ */
21
+ private static readonly CLIENT_LIMIT;
22
+ private static readonly CLIENT_WINDOW_MS;
23
+ /**
24
+ * Per address: 3 requests an hour. A person whose mail is slow asks once or twice more; beyond
25
+ * that it is mail aimed at somebody's inbox.
26
+ */
27
+ private static readonly ACCOUNT_LIMIT;
28
+ private static readonly ACCOUNT_WINDOW_MS;
29
+ private readonly clients;
30
+ private readonly accounts;
31
+ constructor(options?: {
32
+ now?: () => number;
33
+ });
34
+ /** Count this request and answer which window refuses it, if any. */
35
+ admit(client: string, account: string): ThrottleWindow | undefined;
36
+ }
37
+ /** The process-wide windows the reset door shares — they must span requests. */
38
+ export declare const passwordResetThrottle: PasswordResetThrottle;
39
+ //# sourceMappingURL=PasswordResetThrottle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordResetThrottle.d.ts","sourceRoot":"","sources":["../../../src/throttle/PasswordResetThrottle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;;;;;;;GAaG;AACH,qBAAa,qBAAqB;IAChC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAM;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IAE1D;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAK;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAkB;IAE3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE;IAa5C,qEAAqE;IACrE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;CASnE;AAED,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,uBAA8B,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.passwordResetThrottle = exports.PasswordResetThrottle = void 0;
4
+ var SlidingWindow_1 = require("./SlidingWindow");
5
+ /**
6
+ * The password-reset door's two windows (`POST /user/initiate-password-reset`), keyed by digests
7
+ * (`RequestDigests`), never by an address. Both count every request, whether or not the address
8
+ * has an account — a window that only counted real accounts would itself say which addresses
9
+ * have one. Past either window nothing is looked up, minted or mailed; the door's answer is the
10
+ * same sentence as always (see the route).
11
+ *
12
+ * These sit on top of the account row's own five-minute gap between links, which spans replicas
13
+ * (it is stored); the windows are in process memory (`SlidingWindow`): per replica. A
14
+ * deployment of three replicas behind a load balancer (up to ten under load) keeps three sets
15
+ * of windows, so its effective ceiling is ~3× the numbers below (up to ~10×) — for one address
16
+ * still at most one mail per five minutes. Friction, not the wall — a shared store is a
17
+ * separate step.
18
+ */
19
+ var PasswordResetThrottle = /** @class */ (function () {
20
+ function PasswordResetThrottle(options) {
21
+ this.clients = new SlidingWindow_1.SlidingWindow({
22
+ windowMs: PasswordResetThrottle.CLIENT_WINDOW_MS,
23
+ limit: PasswordResetThrottle.CLIENT_LIMIT,
24
+ now: options === null || options === void 0 ? void 0 : options.now,
25
+ });
26
+ this.accounts = new SlidingWindow_1.SlidingWindow({
27
+ windowMs: PasswordResetThrottle.ACCOUNT_WINDOW_MS,
28
+ limit: PasswordResetThrottle.ACCOUNT_LIMIT,
29
+ now: options === null || options === void 0 ? void 0 : options.now,
30
+ });
31
+ }
32
+ /** Count this request and answer which window refuses it, if any. */
33
+ PasswordResetThrottle.prototype.admit = function (client, account) {
34
+ if (this.clients.hit(client)) {
35
+ return 'client';
36
+ }
37
+ if (this.accounts.hit(account)) {
38
+ return 'account';
39
+ }
40
+ return undefined;
41
+ };
42
+ /**
43
+ * Per client: 10 requests an hour. Someone asking for their own address again, or a household
44
+ * asking for a few addresses, passes; a script sweeping addresses stops at ten.
45
+ */
46
+ PasswordResetThrottle.CLIENT_LIMIT = 10;
47
+ PasswordResetThrottle.CLIENT_WINDOW_MS = 60 * 60 * 1000;
48
+ /**
49
+ * Per address: 3 requests an hour. A person whose mail is slow asks once or twice more; beyond
50
+ * that it is mail aimed at somebody's inbox.
51
+ */
52
+ PasswordResetThrottle.ACCOUNT_LIMIT = 3;
53
+ PasswordResetThrottle.ACCOUNT_WINDOW_MS = 60 * 60 * 1000;
54
+ return PasswordResetThrottle;
55
+ }());
56
+ exports.PasswordResetThrottle = PasswordResetThrottle;
57
+ /** The process-wide windows the reset door shares — they must span requests. */
58
+ exports.passwordResetThrottle = new PasswordResetThrottle();
59
+ //# sourceMappingURL=PasswordResetThrottle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordResetThrottle.js","sourceRoot":"","sources":["../../../src/throttle/PasswordResetThrottle.ts"],"names":[],"mappings":";;;AAAA,iDAAgD;AAGhD;;;;;;;;;;;;;GAaG;AACH;IAkBE,+BAAY,OAAgC;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,6BAAa,CAAC;YAC/B,QAAQ,EAAE,qBAAqB,CAAC,gBAAgB;YAChD,KAAK,EAAE,qBAAqB,CAAC,YAAY;YACzC,GAAG,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,6BAAa,CAAC;YAChC,QAAQ,EAAE,qBAAqB,CAAC,iBAAiB;YACjD,KAAK,EAAE,qBAAqB,CAAC,aAAa;YAC1C,GAAG,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG;SAClB,CAAC,CAAC;IACL,CAAC;IAED,qEAAqE;IACrE,qCAAK,GAAL,UAAM,MAAc,EAAE,OAAe;QACnC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC5B,OAAO,QAAQ,CAAC;SACjB;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YAC9B,OAAO,SAAS,CAAC;SAClB;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAvCD;;;OAGG;IACqB,kCAAY,GAAG,EAAE,CAAC;IAClB,sCAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAE1D;;;OAGG;IACqB,mCAAa,GAAG,CAAC,CAAC;IAClB,uCAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IA4B7D,4BAAC;CAAA,AAzCD,IAyCC;AAzCY,sDAAqB;AA2ClC,gFAAgF;AACnE,QAAA,qBAAqB,GAAG,IAAI,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The two keyed digests the throttled doors key their windows on and write on their log lines,
3
+ * in place of what they stand for:
4
+ * - `account(email)` — the ACCOUNT DIGEST: a keyed hash of the trimmed, lowercased address.
5
+ * One address gives one digest however it was typed, on every replica and across restarts, so
6
+ * an operator can say "one account" across lines without the address.
7
+ * - `coarseIp(address)` — the COARSE IP HASH: a keyed hash of the client address at the grain
8
+ * one device holds (an IPv4 address; an IPv6 /64, inside which a device rotates freely), so
9
+ * an operator can say "one device" and a throttle cannot be dodged by rotating inside a /64.
10
+ *
11
+ * Keyed with HMAC-SHA256 under a key DERIVED from the session secret — the one secret every
12
+ * replica already shares, the same keying the invite-request door's IP hash uses; derived per
13
+ * purpose, never used raw, so neither digest weakens the session's own use of it, and the two
14
+ * digests never collide in meaning. Truncated to 64 bits: enough to tell accounts and devices
15
+ * apart, useless to anyone without the key — never the address, never a plain hash a list of
16
+ * addresses could reverse.
17
+ *
18
+ * The key is the deployment's `SESSION_SECRET` unless the constructor is given one (the tests).
19
+ * Without either the digests refuse to run: a server with no `SESSION_SECRET` has no sessions
20
+ * either (the session middleware refuses to start), so nothing ever runs unkeyed — never a plain
21
+ * hash a list of addresses could reverse, never a per-process key that quietly stops matching
22
+ * across replicas.
23
+ */
24
+ export declare class RequestDigests {
25
+ private readonly options?;
26
+ /** Hex characters kept from the HMAC: 64 bits. */
27
+ private static readonly DIGEST_HEX_LENGTH;
28
+ constructor(options?: {
29
+ secret?: string | undefined;
30
+ } | undefined);
31
+ /** The account digest of an address, however it was typed. */
32
+ account(email: string): string;
33
+ /** The coarse IP hash of a client address (see `ClientAddress`). */
34
+ coarseIp(address: string): string;
35
+ private digest;
36
+ private secret;
37
+ /** An IPv4 address as itself (an IPv4-mapped IPv6 address as its IPv4); an IPv6 address as its /64. */
38
+ private coarsen;
39
+ /** The first four groups (the /64) of an IPv6 address, each without leading zeros; undefined when it does not parse. */
40
+ private ipv6Groups;
41
+ }
42
+ //# sourceMappingURL=RequestDigests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestDigests.d.ts","sourceRoot":"","sources":["../../../src/throttle/RequestDigests.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAHrC,kDAAkD;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAM;gBAElB,OAAO,CAAC;;iBAAqB;IAE1D,8DAA8D;IAC9D,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI9B,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIjC,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,MAAM;IAUd,uGAAuG;IACvG,OAAO,CAAC,OAAO;IAYf,wHAAwH;IACxH,OAAO,CAAC,UAAU;CAwBnB"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestDigests = void 0;
4
+ var crypto_1 = require("crypto");
5
+ /**
6
+ * The two keyed digests the throttled doors key their windows on and write on their log lines,
7
+ * in place of what they stand for:
8
+ * - `account(email)` — the ACCOUNT DIGEST: a keyed hash of the trimmed, lowercased address.
9
+ * One address gives one digest however it was typed, on every replica and across restarts, so
10
+ * an operator can say "one account" across lines without the address.
11
+ * - `coarseIp(address)` — the COARSE IP HASH: a keyed hash of the client address at the grain
12
+ * one device holds (an IPv4 address; an IPv6 /64, inside which a device rotates freely), so
13
+ * an operator can say "one device" and a throttle cannot be dodged by rotating inside a /64.
14
+ *
15
+ * Keyed with HMAC-SHA256 under a key DERIVED from the session secret — the one secret every
16
+ * replica already shares, the same keying the invite-request door's IP hash uses; derived per
17
+ * purpose, never used raw, so neither digest weakens the session's own use of it, and the two
18
+ * digests never collide in meaning. Truncated to 64 bits: enough to tell accounts and devices
19
+ * apart, useless to anyone without the key — never the address, never a plain hash a list of
20
+ * addresses could reverse.
21
+ *
22
+ * The key is the deployment's `SESSION_SECRET` unless the constructor is given one (the tests).
23
+ * Without either the digests refuse to run: a server with no `SESSION_SECRET` has no sessions
24
+ * either (the session middleware refuses to start), so nothing ever runs unkeyed — never a plain
25
+ * hash a list of addresses could reverse, never a per-process key that quietly stops matching
26
+ * across replicas.
27
+ */
28
+ var RequestDigests = /** @class */ (function () {
29
+ function RequestDigests(options) {
30
+ this.options = options;
31
+ }
32
+ /** The account digest of an address, however it was typed. */
33
+ RequestDigests.prototype.account = function (email) {
34
+ return this.digest('account-digest', email.trim().toLowerCase());
35
+ };
36
+ /** The coarse IP hash of a client address (see `ClientAddress`). */
37
+ RequestDigests.prototype.coarseIp = function (address) {
38
+ return this.digest('coarse-ip', this.coarsen(address.trim().toLowerCase()));
39
+ };
40
+ RequestDigests.prototype.digest = function (purpose, value) {
41
+ return (0, crypto_1.createHmac)('sha256', "".concat(purpose, ":").concat(this.secret()))
42
+ .update(value)
43
+ .digest('hex')
44
+ .slice(0, RequestDigests.DIGEST_HEX_LENGTH);
45
+ };
46
+ RequestDigests.prototype.secret = function () {
47
+ var _a, _b;
48
+ var configured = (_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.secret) !== null && _b !== void 0 ? _b : process.env.SESSION_SECRET;
49
+ if (!configured) {
50
+ throw new Error('SESSION_SECRET is not set: the account digest and the coarse IP hash need the key every replica shares');
51
+ }
52
+ return configured;
53
+ };
54
+ /** An IPv4 address as itself (an IPv4-mapped IPv6 address as its IPv4); an IPv6 address as its /64. */
55
+ RequestDigests.prototype.coarsen = function (address) {
56
+ var mapped = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/.exec(address);
57
+ if (mapped) {
58
+ return mapped[1];
59
+ }
60
+ if (!address.includes(':')) {
61
+ return address;
62
+ }
63
+ var groups = this.ipv6Groups(address.split('%')[0]);
64
+ return groups ? "".concat(groups.slice(0, 4).join(':'), "::/64") : address;
65
+ };
66
+ /** The first four groups (the /64) of an IPv6 address, each without leading zeros; undefined when it does not parse. */
67
+ RequestDigests.prototype.ipv6Groups = function (address) {
68
+ var halves = address.split('::');
69
+ if (halves.length > 2) {
70
+ return undefined;
71
+ }
72
+ var parts = function (half) { return (half ? half.split(':') : []); };
73
+ var head = parts(halves[0]);
74
+ var tail = parts(halves[1]);
75
+ // A trailing dotted IPv4 part stands for two groups.
76
+ var groupsIn = function (list) { return list.reduce(function (count, part) { return count + (part.includes('.') ? 2 : 1); }, 0); };
77
+ var missing = 8 - groupsIn(head) - groupsIn(tail);
78
+ if (missing < 0 || (halves.length === 1 && missing !== 0)) {
79
+ return undefined;
80
+ }
81
+ var zeros = [];
82
+ for (var i = 0; i < missing; i++) {
83
+ zeros.push('0');
84
+ }
85
+ var groups = head.concat(zeros, tail).slice(0, 4);
86
+ if (groups.some(function (group) { return !/^[0-9a-f]{1,4}$/.test(group); })) {
87
+ return undefined;
88
+ }
89
+ return groups.map(function (group) { return parseInt(group, 16).toString(16); });
90
+ };
91
+ /** Hex characters kept from the HMAC: 64 bits. */
92
+ RequestDigests.DIGEST_HEX_LENGTH = 16;
93
+ return RequestDigests;
94
+ }());
95
+ exports.RequestDigests = RequestDigests;
96
+ //# sourceMappingURL=RequestDigests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestDigests.js","sourceRoot":"","sources":["../../../src/throttle/RequestDigests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /** Which window refused a try: the client's (its coarse IP hash) or the account's (its digest). */
2
+ export type ThrottleWindow = 'client' | 'account';
3
+ /**
4
+ * The sign-in door's two windows (`POST /user/login`), keyed by digests (`RequestDigests`),
5
+ * never by an address:
6
+ * - per CLIENT: every try that is not a success counts — wrong passwords, blank ones too, the
7
+ * client made them — so one device cannot sweep many accounts; a successful sign-in never
8
+ * counts (it is forgiven the moment it succeeds), so the people behind one shared address
9
+ * signing in do not spend the window on each other;
10
+ * - per ACCOUNT: every try that carries a password counts (a blank submission judges no
11
+ * password, so it never counts), so guesses spread over many devices still stop; a success
12
+ * clears the account's count. A try is counted as it ARRIVES, before it is judged: tries in
13
+ * flight at the same moment cannot all pass the window together.
14
+ *
15
+ * A throttled try is told `ANSWER` whichever window refused it and whether or not the address
16
+ * has an account, in the same time a refused password takes (the door runs the same password
17
+ * check and discards its verdict).
18
+ *
19
+ * The windows are in process memory (`SlidingWindow`): per replica. A deployment of three
20
+ * replicas behind a load balancer (up to ten under load) keeps three sets of windows, so its
21
+ * effective ceiling is ~3× the numbers below (up to ~10×). Friction, not the wall — a shared
22
+ * store is a separate step.
23
+ */
24
+ export declare class SignInThrottle {
25
+ /** What a throttled try is told — in plain words, the same for every address, known or not. */
26
+ static readonly ANSWER = "Too many attempts. Try again in a few minutes.";
27
+ /**
28
+ * Per client: 50 tries that are not successes in 10 minutes (the founder's number, 2026-09-23).
29
+ * Successes never count, so an office or a school behind one address signing in at nine o'clock
30
+ * never spends this window on itself — only its mistypes do, and fifty wrong or blank tries in
31
+ * ten minutes is beyond any human population behind one address; a guessing script from one
32
+ * device is held to ~300 tries an hour per replica.
33
+ */
34
+ private static readonly CLIENT_LIMIT;
35
+ private static readonly CLIENT_WINDOW_MS;
36
+ /**
37
+ * Per account: 10 tries in 15 minutes (a success clears them, so only wrong ones ever add up).
38
+ * Someone who has forgotten a password tries a handful and asks for a reset link; ten wrong in
39
+ * a quarter of an hour is guessing, and counting per account holds however many devices the
40
+ * guesses come from. "A few minutes" in the answer is honest: the oldest try leaves the window
41
+ * within 15.
42
+ */
43
+ private static readonly ACCOUNT_LIMIT;
44
+ private static readonly ACCOUNT_WINDOW_MS;
45
+ private readonly clients;
46
+ private readonly accounts;
47
+ constructor(options?: {
48
+ now?: () => number;
49
+ });
50
+ /**
51
+ * Count this try against the client and against the account, and answer which window refuses
52
+ * it, if any. `account` is the digest of the address tried, given only when a password came
53
+ * with it (a blank submission judges no password, so it never counts toward an account). The
54
+ * count is taken here, before the try is judged, so tries in flight at once cannot all pass
55
+ * the window; a success clears it (`recordSuccess`).
56
+ */
57
+ admit(client: string, account?: string): ThrottleWindow | undefined;
58
+ /**
59
+ * The account proved itself: its window opens again. When it was a sign-in try from `client`
60
+ * (rather than a reset link redeemed), that try is forgiven — a success never counts against
61
+ * the device.
62
+ */
63
+ recordSuccess(account: string, client?: string): void;
64
+ }
65
+ /** The process-wide windows the sign-in door shares — they must span requests. */
66
+ export declare const signInThrottle: SignInThrottle;
67
+ //# sourceMappingURL=SignInThrottle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignInThrottle.d.ts","sourceRoot":"","sources":["../../../src/throttle/SignInThrottle.ts"],"names":[],"mappings":"AAEA,mGAAmG;AACnG,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,cAAc;IACzB,+FAA+F;IAC/F,MAAM,CAAC,QAAQ,CAAC,MAAM,oDAAoD;IAE1E;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAM;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IAE1D;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAM;IAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAkB;IAE3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE;IAa5C;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAUnE;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAMtD;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,gBAAuB,CAAC"}