@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
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signInThrottle = exports.SignInThrottle = void 0;
4
+ var SlidingWindow_1 = require("./SlidingWindow");
5
+ /**
6
+ * The sign-in door's two windows (`POST /user/login`), keyed by digests (`RequestDigests`),
7
+ * never by an address:
8
+ * - per CLIENT: every try that is not a success counts — wrong passwords, blank ones too, the
9
+ * client made them — so one device cannot sweep many accounts; a successful sign-in never
10
+ * counts (it is forgiven the moment it succeeds), so the people behind one shared address
11
+ * signing in do not spend the window on each other;
12
+ * - per ACCOUNT: every try that carries a password counts (a blank submission judges no
13
+ * password, so it never counts), so guesses spread over many devices still stop; a success
14
+ * clears the account's count. A try is counted as it ARRIVES, before it is judged: tries in
15
+ * flight at the same moment cannot all pass the window together.
16
+ *
17
+ * A throttled try is told `ANSWER` whichever window refused it and whether or not the address
18
+ * has an account, in the same time a refused password takes (the door runs the same password
19
+ * check and discards its verdict).
20
+ *
21
+ * The windows are in process memory (`SlidingWindow`): per replica. A deployment of three
22
+ * replicas behind a load balancer (up to ten under load) keeps three sets of windows, so its
23
+ * effective ceiling is ~3× the numbers below (up to ~10×). Friction, not the wall — a shared
24
+ * store is a separate step.
25
+ */
26
+ var SignInThrottle = /** @class */ (function () {
27
+ function SignInThrottle(options) {
28
+ this.clients = new SlidingWindow_1.SlidingWindow({
29
+ windowMs: SignInThrottle.CLIENT_WINDOW_MS,
30
+ limit: SignInThrottle.CLIENT_LIMIT,
31
+ now: options === null || options === void 0 ? void 0 : options.now,
32
+ });
33
+ this.accounts = new SlidingWindow_1.SlidingWindow({
34
+ windowMs: SignInThrottle.ACCOUNT_WINDOW_MS,
35
+ limit: SignInThrottle.ACCOUNT_LIMIT,
36
+ now: options === null || options === void 0 ? void 0 : options.now,
37
+ });
38
+ }
39
+ /**
40
+ * Count this try against the client and against the account, and answer which window refuses
41
+ * it, if any. `account` is the digest of the address tried, given only when a password came
42
+ * with it (a blank submission judges no password, so it never counts toward an account). The
43
+ * count is taken here, before the try is judged, so tries in flight at once cannot all pass
44
+ * the window; a success clears it (`recordSuccess`).
45
+ */
46
+ SignInThrottle.prototype.admit = function (client, account) {
47
+ if (this.clients.hit(client)) {
48
+ return 'client';
49
+ }
50
+ if (account !== undefined && this.accounts.hit(account)) {
51
+ return 'account';
52
+ }
53
+ return undefined;
54
+ };
55
+ /**
56
+ * The account proved itself: its window opens again. When it was a sign-in try from `client`
57
+ * (rather than a reset link redeemed), that try is forgiven — a success never counts against
58
+ * the device.
59
+ */
60
+ SignInThrottle.prototype.recordSuccess = function (account, client) {
61
+ this.accounts.clear(account);
62
+ if (client !== undefined) {
63
+ this.clients.forgive(client);
64
+ }
65
+ };
66
+ /** What a throttled try is told — in plain words, the same for every address, known or not. */
67
+ SignInThrottle.ANSWER = 'Too many attempts. Try again in a few minutes.';
68
+ /**
69
+ * Per client: 50 tries that are not successes in 10 minutes (the founder's number, 2026-09-23).
70
+ * Successes never count, so an office or a school behind one address signing in at nine o'clock
71
+ * never spends this window on itself — only its mistypes do, and fifty wrong or blank tries in
72
+ * ten minutes is beyond any human population behind one address; a guessing script from one
73
+ * device is held to ~300 tries an hour per replica.
74
+ */
75
+ SignInThrottle.CLIENT_LIMIT = 50;
76
+ SignInThrottle.CLIENT_WINDOW_MS = 10 * 60 * 1000;
77
+ /**
78
+ * Per account: 10 tries in 15 minutes (a success clears them, so only wrong ones ever add up).
79
+ * Someone who has forgotten a password tries a handful and asks for a reset link; ten wrong in
80
+ * a quarter of an hour is guessing, and counting per account holds however many devices the
81
+ * guesses come from. "A few minutes" in the answer is honest: the oldest try leaves the window
82
+ * within 15.
83
+ */
84
+ SignInThrottle.ACCOUNT_LIMIT = 10;
85
+ SignInThrottle.ACCOUNT_WINDOW_MS = 15 * 60 * 1000;
86
+ return SignInThrottle;
87
+ }());
88
+ exports.SignInThrottle = SignInThrottle;
89
+ /** The process-wide windows the sign-in door shares — they must span requests. */
90
+ exports.signInThrottle = new SignInThrottle();
91
+ //# sourceMappingURL=SignInThrottle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignInThrottle.js","sourceRoot":"","sources":["../../../src/throttle/SignInThrottle.ts"],"names":[],"mappings":";;;AAAA,iDAAgD;AAKhD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IA2BE,wBAAY,OAAgC;QAC1C,IAAI,CAAC,OAAO,GAAG,IAAI,6BAAa,CAAC;YAC/B,QAAQ,EAAE,cAAc,CAAC,gBAAgB;YACzC,KAAK,EAAE,cAAc,CAAC,YAAY;YAClC,GAAG,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,6BAAa,CAAC;YAChC,QAAQ,EAAE,cAAc,CAAC,iBAAiB;YAC1C,KAAK,EAAE,cAAc,CAAC,aAAa;YACnC,GAAG,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,GAAG;SAClB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,8BAAK,GAAL,UAAM,MAAc,EAAE,OAAgB;QACpC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC5B,OAAO,QAAQ,CAAC;SACjB;QACD,IAAI,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YACvD,OAAO,SAAS,CAAC;SAClB;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,sCAAa,GAAb,UAAc,OAAe,EAAE,MAAe;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,MAAM,KAAK,SAAS,EAAE;YACxB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAC9B;IACH,CAAC;IAlED,+FAA+F;IAC/E,qBAAM,GAAG,gDAAgD,CAAC;IAE1E;;;;;;OAMG;IACqB,2BAAY,GAAG,EAAE,CAAC;IAClB,+BAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAE1D;;;;;;OAMG;IACqB,4BAAa,GAAG,EAAE,CAAC;IACnB,gCAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IA8C7D,qBAAC;CAAA,AApED,IAoEC;AApEY,wCAAc;AAsE3B,kFAAkF;AACrE,QAAA,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * A per-key sliding window: how many attempts a key made in the last `windowMs`, against a
3
+ * `limit`. The one window every throttled door shares — the sign-in and password-reset doors in
4
+ * this package, and any consumer door throttling per client (lifted from the invite-request
5
+ * door's per-IP throttle, which it replaces).
6
+ *
7
+ * Held in process memory only, which is what makes it cheap and what bounds it:
8
+ * - PER PROCESS. Each replica keeps its own windows, so behind a load balancer spreading a
9
+ * client over N replicas the effective ceiling is ~N× the limit; a restart forgets them.
10
+ * A throttle built on this is friction, not the wall. A shared store is a separate step.
11
+ * - BOUNDED. At most `maxKeys` keys are tracked; at the bound the oldest-touched key is
12
+ * forgotten first, so a flood of fresh keys degrades the friction before it grows memory.
13
+ *
14
+ * Keys are whatever the caller passes — callers pass digests (see `RequestDigests`), never raw
15
+ * addresses, so nothing identifying is held here either.
16
+ */
17
+ export declare class SlidingWindow {
18
+ private static readonly DEFAULT_MAX_KEYS;
19
+ private readonly windowMs;
20
+ private readonly limit;
21
+ private readonly maxKeys;
22
+ private readonly now;
23
+ /** key → the counted attempt times inside the window (pruned on touch), in touch order. */
24
+ private readonly attempts;
25
+ constructor(options: {
26
+ windowMs: number;
27
+ limit: number;
28
+ maxKeys?: number;
29
+ now?: () => number;
30
+ });
31
+ /**
32
+ * Record an attempt for `key` and answer whether it was over the window — `true` means refuse.
33
+ * A refused attempt is not counted, so a key drains one window after its last counted attempt.
34
+ */
35
+ hit(key: string): boolean;
36
+ /** Whether `key` has used up its window, without counting anything. */
37
+ isOver(key: string): boolean;
38
+ /** Count an attempt for `key` without answering (for doors that judge the attempt first). */
39
+ record(key: string): void;
40
+ /** Forget `key`'s attempts. */
41
+ clear(key: string): void;
42
+ /**
43
+ * Uncount `key`'s latest attempt (for doors that count a try as it arrives and learn afterwards
44
+ * that it should never have counted — a sign-in that succeeded).
45
+ */
46
+ forgive(key: string): void;
47
+ private inWindow;
48
+ /** Store `key`'s attempts as the most recently touched, evicting the oldest-touched key at the bound. */
49
+ private touch;
50
+ }
51
+ //# sourceMappingURL=SlidingWindow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlidingWindow.d.ts","sourceRoot":"","sources":["../../../src/throttle/SlidingWindow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAElD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;gBAE5C,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;KAAE;IAO9F;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASzB,uEAAuE;IACvE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B,6FAA6F;IAC7F,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAMzB,+BAA+B;IAC/B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM1B,OAAO,CAAC,QAAQ;IAKhB,yGAAyG;IACzG,OAAO,CAAC,KAAK;CAUd"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlidingWindow = void 0;
4
+ /**
5
+ * A per-key sliding window: how many attempts a key made in the last `windowMs`, against a
6
+ * `limit`. The one window every throttled door shares — the sign-in and password-reset doors in
7
+ * this package, and any consumer door throttling per client (lifted from the invite-request
8
+ * door's per-IP throttle, which it replaces).
9
+ *
10
+ * Held in process memory only, which is what makes it cheap and what bounds it:
11
+ * - PER PROCESS. Each replica keeps its own windows, so behind a load balancer spreading a
12
+ * client over N replicas the effective ceiling is ~N× the limit; a restart forgets them.
13
+ * A throttle built on this is friction, not the wall. A shared store is a separate step.
14
+ * - BOUNDED. At most `maxKeys` keys are tracked; at the bound the oldest-touched key is
15
+ * forgotten first, so a flood of fresh keys degrades the friction before it grows memory.
16
+ *
17
+ * Keys are whatever the caller passes — callers pass digests (see `RequestDigests`), never raw
18
+ * addresses, so nothing identifying is held here either.
19
+ */
20
+ var SlidingWindow = /** @class */ (function () {
21
+ function SlidingWindow(options) {
22
+ var _a, _b;
23
+ /** key → the counted attempt times inside the window (pruned on touch), in touch order. */
24
+ this.attempts = new Map();
25
+ this.windowMs = options.windowMs;
26
+ this.limit = options.limit;
27
+ this.maxKeys = (_a = options.maxKeys) !== null && _a !== void 0 ? _a : SlidingWindow.DEFAULT_MAX_KEYS;
28
+ this.now = (_b = options.now) !== null && _b !== void 0 ? _b : Date.now;
29
+ }
30
+ /**
31
+ * Record an attempt for `key` and answer whether it was over the window — `true` means refuse.
32
+ * A refused attempt is not counted, so a key drains one window after its last counted attempt.
33
+ */
34
+ SlidingWindow.prototype.hit = function (key) {
35
+ if (this.isOver(key)) {
36
+ this.touch(key, this.inWindow(key));
37
+ return true;
38
+ }
39
+ this.record(key);
40
+ return false;
41
+ };
42
+ /** Whether `key` has used up its window, without counting anything. */
43
+ SlidingWindow.prototype.isOver = function (key) {
44
+ return this.inWindow(key).length >= this.limit;
45
+ };
46
+ /** Count an attempt for `key` without answering (for doors that judge the attempt first). */
47
+ SlidingWindow.prototype.record = function (key) {
48
+ var attempts = this.inWindow(key);
49
+ attempts.push(this.now());
50
+ this.touch(key, attempts);
51
+ };
52
+ /** Forget `key`'s attempts. */
53
+ SlidingWindow.prototype.clear = function (key) {
54
+ this.attempts.delete(key);
55
+ };
56
+ /**
57
+ * Uncount `key`'s latest attempt (for doors that count a try as it arrives and learn afterwards
58
+ * that it should never have counted — a sign-in that succeeded).
59
+ */
60
+ SlidingWindow.prototype.forgive = function (key) {
61
+ var attempts = this.inWindow(key);
62
+ attempts.pop();
63
+ this.touch(key, attempts);
64
+ };
65
+ SlidingWindow.prototype.inWindow = function (key) {
66
+ var _a;
67
+ var cutoff = this.now() - this.windowMs;
68
+ return ((_a = this.attempts.get(key)) !== null && _a !== void 0 ? _a : []).filter(function (time) { return time > cutoff; });
69
+ };
70
+ /** Store `key`'s attempts as the most recently touched, evicting the oldest-touched key at the bound. */
71
+ SlidingWindow.prototype.touch = function (key, attempts) {
72
+ if (!this.attempts.has(key) && this.attempts.size >= this.maxKeys) {
73
+ var oldest = this.attempts.keys().next().value;
74
+ if (oldest !== undefined) {
75
+ this.attempts.delete(oldest);
76
+ }
77
+ }
78
+ this.attempts.delete(key);
79
+ this.attempts.set(key, attempts);
80
+ };
81
+ SlidingWindow.DEFAULT_MAX_KEYS = 10000;
82
+ return SlidingWindow;
83
+ }());
84
+ exports.SlidingWindow = SlidingWindow;
85
+ //# sourceMappingURL=SlidingWindow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlidingWindow.js","sourceRoot":"","sources":["../../../src/throttle/SlidingWindow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ClientAddress.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientAddress.test.d.ts","sourceRoot":"","sources":["../../test/ClientAddress.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var ClientAddress_1 = require("../src/throttle/ClientAddress");
4
+ /**
5
+ * Which address a throttle keys on. Behind Google's external Application Load Balancer the
6
+ * header ends `<client-ip>,<load-balancer-ip>` — the balancer appends both, and anything before
7
+ * them is whatever the client itself sent. So the client is the SECOND entry from the right:
8
+ * never the last (the balancer's own address, the same for every visitor — a throttle keyed on
9
+ * it is one bucket for the whole world) and never the first (client-supplied, rotatable at will).
10
+ */
11
+ describe('ClientAddress', function () {
12
+ var behindTheBalancer = function (forwardedFor, socketAddress) {
13
+ var _a, _b;
14
+ if (socketAddress === void 0) { socketAddress = '35.191.0.10'; }
15
+ return ({
16
+ app: { get: function (setting) { return (setting === 'trust proxy' ? 1 : undefined); } },
17
+ headers: forwardedFor === undefined ? {} : { 'x-forwarded-for': forwardedFor },
18
+ socket: { remoteAddress: socketAddress },
19
+ // What express's own `request.ip` resolves to under `trust proxy 1`: the header's last entry.
20
+ ip: (_b = (_a = forwardedFor === null || forwardedFor === void 0 ? void 0 : forwardedFor.split(',').pop()) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : socketAddress,
21
+ });
22
+ };
23
+ it("reads the client the balancer appended, not the balancer's own address", function () {
24
+ var request = behindTheBalancer('198.51.100.23, 34.120.1.1');
25
+ expect(new ClientAddress_1.ClientAddress().of(request)).toBe('198.51.100.23');
26
+ expect(request.ip).toBe('34.120.1.1');
27
+ });
28
+ it('ignores whatever the client put in the header itself', function () {
29
+ var spoofed = behindTheBalancer('203.0.113.99, 10.0.0.1, 198.51.100.23, 34.120.1.1');
30
+ expect(new ClientAddress_1.ClientAddress().of(spoofed)).toBe('198.51.100.23');
31
+ });
32
+ it('reads IPv6 clients the same way', function () {
33
+ expect(new ClientAddress_1.ClientAddress().of(behindTheBalancer('2001:db8:1:2:3:4:5:6,34.120.1.1'))).toBe('2001:db8:1:2:3:4:5:6');
34
+ });
35
+ it('a request that did not come through the balancer (no appended pair) keys on its own connection', function () {
36
+ expect(new ClientAddress_1.ClientAddress().of(behindTheBalancer(undefined, '10.8.0.7'))).toBe('10.8.0.7');
37
+ expect(new ClientAddress_1.ClientAddress().of(behindTheBalancer('10.8.0.9', '10.8.0.7'))).toBe('10.8.0.7');
38
+ });
39
+ it('with no proxy trusted (development) the connection is the client, and a forwarded header is ignored', function () {
40
+ var direct = {
41
+ app: { get: function () { return false; } },
42
+ headers: { 'x-forwarded-for': '203.0.113.99, 198.51.100.23' },
43
+ socket: { remoteAddress: '::1' },
44
+ };
45
+ expect(new ClientAddress_1.ClientAddress().of(direct)).toBe('::1');
46
+ });
47
+ it('a request with no connection details at all reads as the empty address', function () {
48
+ expect(new ClientAddress_1.ClientAddress().of({})).toBe('');
49
+ });
50
+ });
51
+ //# sourceMappingURL=ClientAddress.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientAddress.test.js","sourceRoot":"","sources":["../../test/ClientAddress.test.ts"],"names":[],"mappings":";;AAAA,+DAA8D;AAE9D;;;;;;GAMG;AACH,QAAQ,CAAC,eAAe,EAAE;IACxB,IAAM,iBAAiB,GAAG,UAAC,YAAgC,EAAE,aAA6B;;QAA7B,8BAAA,EAAA,6BAA6B;QAAK,OAAA,CAAC;YAC9F,GAAG,EAAE,EAAE,GAAG,EAAE,UAAC,OAAe,IAAK,OAAA,CAAC,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAA3C,CAA2C,EAAE;YAC9E,OAAO,EAAE,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,YAAY,EAAE;YAC9E,MAAM,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE;YACxC,8FAA8F;YAC9F,EAAE,EAAE,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,0CAAE,IAAI,EAAE,mCAAI,aAAa;SAC5D,CAAC,CAAA;KAAA,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE;QAC3E,IAAM,OAAO,GAAG,iBAAiB,CAAC,2BAA2B,CAAC,CAAC;QAE/D,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC9D,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE;QACzD,IAAM,OAAO,GAAG,iBAAiB,CAAC,mDAAmD,CAAC,CAAC;QAEvF,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE;QACpC,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACpH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gGAAgG,EAAE;QACnG,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1F,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qGAAqG,EAAE;QACxG,IAAM,MAAM,GAAG;YACb,GAAG,EAAE,EAAE,GAAG,EAAE,cAAM,OAAA,KAAK,EAAL,CAAK,EAAE;YACzB,OAAO,EAAE,EAAE,iBAAiB,EAAE,6BAA6B,EAAE;YAC7D,MAAM,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE;SACjC,CAAC;QAEF,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE;QAC3E,MAAM,CAAC,IAAI,6BAAa,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,4 +1,19 @@
1
1
  "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
2
17
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
18
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
19
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -37,6 +52,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
52
  };
38
53
  Object.defineProperty(exports, "__esModule", { value: true });
39
54
  var db_1 = require("@proteinjs/db");
55
+ var reflection_1 = require("@proteinjs/reflection");
40
56
  var user_1 = require("@proteinjs/user");
41
57
  var PasswordHasher_1 = require("../src/authentication/PasswordHasher");
42
58
  var devLoginHarness_1 = require("./devLoginHarness");
@@ -190,6 +206,58 @@ describe('devLogin route', function () {
190
206
  }
191
207
  });
192
208
  }); });
209
+ it('refuses a ?email a machine-account declaration owns with 400 in plain words — no session, no row', function () { return __awaiter(void 0, void 0, void 0, function () {
210
+ var DeclaredMachineAccount, repo, outcome, _a;
211
+ return __generator(this, function (_b) {
212
+ switch (_b.label) {
213
+ case 0:
214
+ DeclaredMachineAccount = /** @class */ (function (_super) {
215
+ __extends(DeclaredMachineAccount, _super);
216
+ // The declared machine accounts of the build are the list signup refuses from; the dev door
217
+ // creates missing accounts through the same function and must answer the way its other
218
+ // refusals do — in words, not as an unhandled throw.
219
+ function DeclaredMachineAccount() {
220
+ var _this = _super !== null && _super.apply(this, arguments) || this;
221
+ _this.id = 'declared-machine';
222
+ _this.email = 'declared.machine@test.local';
223
+ _this.accountName = 'Declared machine';
224
+ _this.roles = [];
225
+ _this.secretName = 'declared-machine-secret';
226
+ return _this;
227
+ }
228
+ return DeclaredMachineAccount;
229
+ }(user_1.MachineAccount));
230
+ repo = reflection_1.SourceRepository.get();
231
+ repo.namedObjectCache['@proteinjs/db/SourceRecordLoader'] = [
232
+ {
233
+ qualifiedName: '@proteinjs/user-server-test/DeclaredMachineAccount',
234
+ packageName: '@test/declarer',
235
+ object: new DeclaredMachineAccount(),
236
+ },
237
+ ];
238
+ _b.label = 1;
239
+ case 1:
240
+ _b.trys.push([1, , 4, 5]);
241
+ return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'declared.machine@test.local' })];
242
+ case 2:
243
+ outcome = _b.sent();
244
+ expect(outcome.status).toBe(400);
245
+ expect(String(outcome.body)).toContain("This address can't be registered.");
246
+ expect(outcome.loggedInAs).toBeUndefined();
247
+ expect(outcome.sessionSaved).toBe(false);
248
+ expect(outcome.redirect).toBeUndefined();
249
+ _a = expect;
250
+ return [4 /*yield*/, getUserRow('declared.machine@test.local')];
251
+ case 3:
252
+ _a.apply(void 0, [_b.sent()]).toBeUndefined();
253
+ return [3 /*break*/, 5];
254
+ case 4:
255
+ delete repo.namedObjectCache['@proteinjs/db/SourceRecordLoader'];
256
+ return [7 /*endfinally*/];
257
+ case 5: return [2 /*return*/];
258
+ }
259
+ });
260
+ }); });
193
261
  it('rejects a malformed same-domain ?email with 400 — no session, no stray account', function () { return __awaiter(void 0, void 0, void 0, function () {
194
262
  var malformed, outcome, _a;
195
263
  return __generator(this, function (_b) {
@@ -1 +1 @@
1
- {"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":"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"}