@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.
- package/CHANGELOG.md +28 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/src/authentication/PasswordHasher.d.ts +9 -0
- package/dist/src/authentication/PasswordHasher.d.ts.map +1 -1
- package/dist/src/authentication/PasswordHasher.js +25 -0
- package/dist/src/authentication/PasswordHasher.js.map +1 -1
- package/dist/src/authentication/SocketIOSessionWatcher.d.ts +5 -0
- package/dist/src/authentication/SocketIOSessionWatcher.d.ts.map +1 -1
- package/dist/src/authentication/SocketIOSessionWatcher.js +13 -2
- package/dist/src/authentication/SocketIOSessionWatcher.js.map +1 -1
- package/dist/src/authentication/UserStatusTableWatcher.d.ts.map +1 -1
- package/dist/src/authentication/UserStatusTableWatcher.js +2 -1
- package/dist/src/authentication/UserStatusTableWatcher.js.map +1 -1
- package/dist/src/authentication/authenticate.d.ts +15 -0
- package/dist/src/authentication/authenticate.d.ts.map +1 -1
- package/dist/src/authentication/authenticate.js +55 -20
- package/dist/src/authentication/authenticate.js.map +1 -1
- package/dist/src/authorization/userCache.d.ts.map +1 -1
- package/dist/src/authorization/userCache.js +3 -2
- package/dist/src/authorization/userCache.js.map +1 -1
- package/dist/src/routes/devLogin.d.ts.map +1 -1
- package/dist/src/routes/devLogin.js +29 -14
- package/dist/src/routes/devLogin.js.map +1 -1
- package/dist/src/routes/executePasswordReset.d.ts +4 -0
- package/dist/src/routes/executePasswordReset.d.ts.map +1 -1
- package/dist/src/routes/executePasswordReset.js +12 -4
- package/dist/src/routes/executePasswordReset.js.map +1 -1
- package/dist/src/routes/initiatePasswordReset.d.ts +7 -0
- package/dist/src/routes/initiatePasswordReset.d.ts.map +1 -1
- package/dist/src/routes/initiatePasswordReset.js +28 -10
- package/dist/src/routes/initiatePasswordReset.js.map +1 -1
- package/dist/src/routes/login.d.ts +8 -0
- package/dist/src/routes/login.d.ts.map +1 -1
- package/dist/src/routes/login.js +63 -22
- package/dist/src/routes/login.js.map +1 -1
- package/dist/src/routes/signup.d.ts.map +1 -1
- package/dist/src/routes/signup.js +5 -2
- package/dist/src/routes/signup.js.map +1 -1
- package/dist/src/routes/validateResetPasswordToken.d.ts.map +1 -1
- package/dist/src/routes/validateResetPasswordToken.js +5 -1
- package/dist/src/routes/validateResetPasswordToken.js.map +1 -1
- package/dist/src/services/MachineCredentials.d.ts +10 -1
- package/dist/src/services/MachineCredentials.d.ts.map +1 -1
- package/dist/src/services/MachineCredentials.js +46 -15
- package/dist/src/services/MachineCredentials.js.map +1 -1
- package/dist/src/services/Roles.d.ts.map +1 -1
- package/dist/src/services/Roles.js +6 -2
- package/dist/src/services/Roles.js.map +1 -1
- package/dist/src/services/Signup.d.ts +5 -0
- package/dist/src/services/Signup.d.ts.map +1 -1
- package/dist/src/services/Signup.js +28 -6
- package/dist/src/services/Signup.js.map +1 -1
- package/dist/src/throttle/ClientAddress.d.ts +35 -0
- package/dist/src/throttle/ClientAddress.d.ts.map +1 -0
- package/dist/src/throttle/ClientAddress.js +48 -0
- package/dist/src/throttle/ClientAddress.js.map +1 -0
- package/dist/src/throttle/PasswordResetThrottle.d.ts +39 -0
- package/dist/src/throttle/PasswordResetThrottle.d.ts.map +1 -0
- package/dist/src/throttle/PasswordResetThrottle.js +59 -0
- package/dist/src/throttle/PasswordResetThrottle.js.map +1 -0
- package/dist/src/throttle/RequestDigests.d.ts +42 -0
- package/dist/src/throttle/RequestDigests.d.ts.map +1 -0
- package/dist/src/throttle/RequestDigests.js +96 -0
- package/dist/src/throttle/RequestDigests.js.map +1 -0
- package/dist/src/throttle/SignInThrottle.d.ts +67 -0
- package/dist/src/throttle/SignInThrottle.d.ts.map +1 -0
- package/dist/src/throttle/SignInThrottle.js +91 -0
- package/dist/src/throttle/SignInThrottle.js.map +1 -0
- package/dist/src/throttle/SlidingWindow.d.ts +51 -0
- package/dist/src/throttle/SlidingWindow.d.ts.map +1 -0
- package/dist/src/throttle/SlidingWindow.js +85 -0
- package/dist/src/throttle/SlidingWindow.js.map +1 -0
- package/dist/test/ClientAddress.test.d.ts +2 -0
- package/dist/test/ClientAddress.test.d.ts.map +1 -0
- package/dist/test/ClientAddress.test.js +51 -0
- package/dist/test/ClientAddress.test.js.map +1 -0
- package/dist/test/DevLogin.test.js +68 -0
- package/dist/test/DevLogin.test.js.map +1 -1
- package/dist/test/InitiatePasswordReset.test.js +373 -5
- package/dist/test/InitiatePasswordReset.test.js.map +1 -1
- package/dist/test/LogCapture.d.ts +10 -0
- package/dist/test/LogCapture.d.ts.map +1 -1
- package/dist/test/LogCapture.js +19 -0
- package/dist/test/LogCapture.js.map +1 -1
- package/dist/test/LogCapture.test.d.ts +2 -0
- package/dist/test/LogCapture.test.d.ts.map +1 -0
- package/dist/test/LogCapture.test.js +86 -0
- package/dist/test/LogCapture.test.js.map +1 -0
- package/dist/test/LoginThrottle.integration.test.d.ts +2 -0
- package/dist/test/LoginThrottle.integration.test.d.ts.map +1 -0
- package/dist/test/LoginThrottle.integration.test.js +616 -0
- package/dist/test/LoginThrottle.integration.test.js.map +1 -0
- package/dist/test/MachineAccounts.integration.test.js +156 -28
- package/dist/test/MachineAccounts.integration.test.js.map +1 -1
- package/dist/test/NoAddressesInLogs.integration.test.d.ts +2 -0
- package/dist/test/NoAddressesInLogs.integration.test.d.ts.map +1 -0
- package/dist/test/NoAddressesInLogs.integration.test.js +717 -0
- package/dist/test/NoAddressesInLogs.integration.test.js.map +1 -0
- package/dist/test/RequestDigests.test.d.ts +2 -0
- package/dist/test/RequestDigests.test.d.ts.map +1 -0
- package/dist/test/RequestDigests.test.js +73 -0
- package/dist/test/RequestDigests.test.js.map +1 -0
- package/dist/test/SignupRoute.test.js +80 -1
- package/dist/test/SignupRoute.test.js.map +1 -1
- package/dist/test/SlidingWindow.test.d.ts +2 -0
- package/dist/test/SlidingWindow.test.d.ts.map +1 -0
- package/dist/test/SlidingWindow.test.js +72 -0
- package/dist/test/SlidingWindow.test.js.map +1 -0
- package/dist/test/SocketIOSessionWatcher.test.d.ts +2 -0
- package/dist/test/SocketIOSessionWatcher.test.d.ts.map +1 -0
- package/dist/test/SocketIOSessionWatcher.test.js +144 -0
- package/dist/test/SocketIOSessionWatcher.test.js.map +1 -0
- package/generated/index.ts +1 -1
- package/index.ts +5 -0
- package/package.json +6 -5
- package/src/authentication/PasswordHasher.ts +18 -1
- package/src/authentication/SocketIOSessionWatcher.ts +13 -1
- package/src/authentication/UserStatusTableWatcher.ts +2 -1
- package/src/authentication/authenticate.ts +36 -9
- package/src/authorization/userCache.ts +3 -2
- package/src/routes/devLogin.ts +22 -10
- package/src/routes/executePasswordReset.ts +11 -3
- package/src/routes/initiatePasswordReset.ts +29 -11
- package/src/routes/login.ts +39 -8
- package/src/routes/signup.ts +5 -2
- package/src/routes/validateResetPasswordToken.ts +5 -1
- package/src/services/MachineCredentials.ts +44 -9
- package/src/services/Roles.ts +6 -2
- package/src/services/Signup.ts +30 -4
- package/src/throttle/ClientAddress.ts +47 -0
- package/src/throttle/PasswordResetThrottle.ts +62 -0
- package/src/throttle/RequestDigests.ts +97 -0
- package/src/throttle/SignInThrottle.ts +98 -0
- package/src/throttle/SlidingWindow.ts +90 -0
- package/test/ClientAddress.test.ts +54 -0
- package/test/DevLogin.test.ts +35 -1
- package/test/InitiatePasswordReset.test.ts +212 -6
- package/test/LogCapture.test.ts +29 -0
- package/test/LogCapture.ts +16 -0
- package/test/LoginThrottle.integration.test.ts +339 -0
- package/test/MachineAccounts.integration.test.ts +97 -22
- package/test/NoAddressesInLogs.integration.test.ts +409 -0
- package/test/RequestDigests.test.ts +81 -0
- package/test/SignupRoute.test.ts +54 -1
- package/test/SlidingWindow.test.ts +85 -0
- package/test/SocketIOSessionWatcher.test.ts +86 -0
- package/test/setup.js +2 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordHasher.d.ts","sourceRoot":"","sources":["../../../src/authentication/PasswordHasher.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IACzB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAKpC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAgB;
|
|
1
|
+
{"version":3,"file":"PasswordHasher.d.ts","sourceRoot":"","sources":["../../../src/authentication/PasswordHasher.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAc;IACzB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAKpC;IAEF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAEvD,iIAAiI;IACjI,OAAO,CAAC,MAAM,CAAC,OAAO,CAA8B;IAE9C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,gBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ/E;;;OAGG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYvF;;;;;OAKG;IACG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAQ5D;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,GAAE,gBAA0B,GAAG,OAAO;IAQ1E,uGAAuG;IACvG,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,iBAAiB;CAK1B"}
|
|
@@ -113,6 +113,31 @@ var PasswordHasher = /** @class */ (function () {
|
|
|
113
113
|
});
|
|
114
114
|
});
|
|
115
115
|
};
|
|
116
|
+
/**
|
|
117
|
+
* Spends what verifying a human credential spends, and matches nothing: the refusal for an
|
|
118
|
+
* address with no account pays the same argon2 verification a wrong password pays, so how
|
|
119
|
+
* long a refusal takes says nothing about whether the address has an account. (The stand-in
|
|
120
|
+
* hash is minted on the first call; that one call also pays a hash.)
|
|
121
|
+
*/
|
|
122
|
+
PasswordHasher.prototype.verifyAgainstNothing = function (password) {
|
|
123
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
124
|
+
var _a, _b;
|
|
125
|
+
return __generator(this, function (_c) {
|
|
126
|
+
switch (_c.label) {
|
|
127
|
+
case 0:
|
|
128
|
+
if (!PasswordHasher.standIn) {
|
|
129
|
+
PasswordHasher.standIn = argon2.hash((0, crypto_1.randomBytes)(32).toString('hex'), PasswordHasher.ARGON2_OPTIONS);
|
|
130
|
+
}
|
|
131
|
+
_b = (_a = argon2).verify;
|
|
132
|
+
return [4 /*yield*/, PasswordHasher.standIn];
|
|
133
|
+
case 1: return [4 /*yield*/, _b.apply(_a, [_c.sent(), password])];
|
|
134
|
+
case 2:
|
|
135
|
+
_c.sent();
|
|
136
|
+
return [2 /*return*/, false];
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
};
|
|
116
141
|
/**
|
|
117
142
|
* True when a verified credential should be re-written in the current format: legacy sha256
|
|
118
143
|
* under `human` mode. Machine rows never rehash — sha256 IS their current format.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PasswordHasher.js","sourceRoot":"","sources":["../../../src/authentication/PasswordHasher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"PasswordHasher.js","sourceRoot":"","sources":["../../../src/authentication/PasswordHasher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iCAAkE;AAClE,6CAAiC;AAUjC;;;;;;;;;;;;GAYG;AACH;IAAA;IA+EA,CAAC;IA5DO,6BAAI,GAAV,UAAW,QAAgB,EAAE,IAAgC;QAAhC,qBAAA,EAAA,cAAgC;;;;;wBAC3D,IAAI,IAAI,KAAK,SAAS,EAAE;4BACtB,sBAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAC;yBACjC;wBAEM,qBAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,EAAA;4BAAjE,sBAAO,SAA0D,EAAC;;;;KACnE;IAED;;;OAGG;IACG,+BAAM,GAAZ,UAAa,UAAqC,EAAE,QAAgB;;;;;wBAClE,IAAI,CAAC,UAAU,EAAE;4BACf,sBAAO,KAAK,EAAC;yBACd;6BAEG,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,eAAe,CAAC,EAArD,wBAAqD;wBAChD,qBAAM,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAA;4BAAhD,sBAAO,SAAyC,EAAC;4BAGnD,sBAAO,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAC;;;;KACrE;IAED;;;;;OAKG;IACG,6CAAoB,GAA1B,UAA2B,QAAgB;;;;;;wBACzC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;4BAC3B,cAAc,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC;yBACtG;wBACK,KAAA,CAAA,KAAA,MAAM,CAAA,CAAC,MAAM,CAAA;wBAAC,qBAAM,cAAc,CAAC,OAAO,EAAA;4BAAhD,qBAAM,cAAc,SAA4B,EAAE,QAAQ,EAAC,EAAA;;wBAA3D,SAA2D,CAAC;wBAC5D,sBAAO,KAAK,EAAC;;;;KACd;IAED;;;OAGG;IACH,oCAAW,GAAX,UAAY,UAAkB,EAAE,IAAgC;QAAhC,qBAAA,EAAA,cAAgC;QAC9D,IAAI,IAAI,KAAK,SAAS,EAAE;YACtB,OAAO,KAAK,CAAC;SACd;QAED,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IAChE,CAAC;IAED,uGAAuG;IAC/F,kCAAS,GAAjB,UAAkB,KAAa;QAC7B,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC;IAEO,0CAAiB,GAAzB,UAA0B,MAAc,EAAE,SAAiB;QACzD,IAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,IAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtD,OAAO,WAAW,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM,IAAI,IAAA,wBAAe,EAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IACtG,CAAC;IA7ED;;;;;OAKG;IACqB,6BAAc,GAAuB;QAC3D,IAAI,EAAE,MAAM,CAAC,QAAQ;QACrB,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,CAAC;QACX,WAAW,EAAE,CAAC;KACf,CAAC;IAEsB,8BAAe,GAAG,YAAY,CAAC;IAiEzD,qBAAC;CAAA,AA/ED,IA+EC;AA/EY,wCAAc"}
|
|
@@ -3,6 +3,11 @@ import { Session } from '@proteinjs/user';
|
|
|
3
3
|
/**
|
|
4
4
|
* Handles Socket.IO session cleanup (such as disconnecting sockets)
|
|
5
5
|
* when sessions are deleted.
|
|
6
|
+
*
|
|
7
|
+
* A deletion is not always made by a running server: a boot's source-record sync — and a
|
|
8
|
+
* migration Job, which never starts one — deactivates a withdrawn machine account and deletes its
|
|
9
|
+
* sessions before any socket server exists. Then no socket can be open, and there is nothing to
|
|
10
|
+
* close.
|
|
6
11
|
*/
|
|
7
12
|
export declare class SocketIOSessionWatcher implements TableWatcher<Session> {
|
|
8
13
|
name(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocketIOSessionWatcher.d.ts","sourceRoot":"","sources":["../../../src/authentication/SocketIOSessionWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,OAAO,EAAgB,MAAM,iBAAiB,CAAC;AAGxD
|
|
1
|
+
{"version":3,"file":"SocketIOSessionWatcher.d.ts","sourceRoot":"","sources":["../../../src/authentication/SocketIOSessionWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,OAAO,EAAgB,MAAM,iBAAiB,CAAC;AAGxD;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,YAAW,YAAY,CAAC,OAAO,CAAC;IAClE,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC;IAIjB,WAAW,CAAC,CAAC,SAAS,OAAO,EACjC,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,CAAC,EAAE,EACnB,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,EAC1B,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,IAAI,CAAC;CAWjB"}
|
|
@@ -42,6 +42,11 @@ var server_1 = require("@proteinjs/server");
|
|
|
42
42
|
/**
|
|
43
43
|
* Handles Socket.IO session cleanup (such as disconnecting sockets)
|
|
44
44
|
* when sessions are deleted.
|
|
45
|
+
*
|
|
46
|
+
* A deletion is not always made by a running server: a boot's source-record sync — and a
|
|
47
|
+
* migration Job, which never starts one — deactivates a withdrawn machine account and deletes its
|
|
48
|
+
* sessions before any socket server exists. Then no socket can be open, and there is nothing to
|
|
49
|
+
* close.
|
|
45
50
|
*/
|
|
46
51
|
var SocketIOSessionWatcher = /** @class */ (function () {
|
|
47
52
|
function SocketIOSessionWatcher() {
|
|
@@ -54,10 +59,16 @@ var SocketIOSessionWatcher = /** @class */ (function () {
|
|
|
54
59
|
};
|
|
55
60
|
SocketIOSessionWatcher.prototype.afterDelete = function (recordDeleteCount, deletedRecords, initialQb, deleteQb) {
|
|
56
61
|
return __awaiter(this, void 0, void 0, function () {
|
|
57
|
-
var deletedSessionIds;
|
|
62
|
+
var socketIOServer, deletedSessionIds;
|
|
58
63
|
return __generator(this, function (_a) {
|
|
64
|
+
socketIOServer = server_1.SocketIOServerRepo.getSocketIOServerIfExists();
|
|
59
65
|
deletedSessionIds = deletedRecords.map(function (deletedRecord) { return deletedRecord.sessionId; });
|
|
60
|
-
|
|
66
|
+
// No rooms is never sent: socket.io applies an operation with an empty room list to EVERY
|
|
67
|
+
// socket on the namespace.
|
|
68
|
+
if (!socketIOServer || deletedSessionIds.length === 0) {
|
|
69
|
+
return [2 /*return*/];
|
|
70
|
+
}
|
|
71
|
+
socketIOServer.in(deletedSessionIds).disconnectSockets(true);
|
|
61
72
|
return [2 /*return*/];
|
|
62
73
|
});
|
|
63
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocketIOSessionWatcher.js","sourceRoot":"","sources":["../../../src/authentication/SocketIOSessionWatcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAwD;AACxD,4CAAuD;AAEvD
|
|
1
|
+
{"version":3,"file":"SocketIOSessionWatcher.js","sourceRoot":"","sources":["../../../src/authentication/SocketIOSessionWatcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAwD;AACxD,4CAAuD;AAEvD;;;;;;;;GAQG;AACH;IAAA;IAyBA,CAAC;IAxBC,qCAAI,GAAJ;QACE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,sCAAK,GAAL;QACE,OAAO,IAAI,mBAAY,EAAE,CAAC;IAC5B,CAAC;IAEK,4CAAW,GAAjB,UACE,iBAAyB,EACzB,cAAmB,EACnB,SAA0B,EAC1B,QAAyB;;;;gBAEnB,cAAc,GAAG,2BAAkB,CAAC,yBAAyB,EAAE,CAAC;gBAChE,iBAAiB,GAAG,cAAc,CAAC,GAAG,CAAC,UAAC,aAAa,IAAK,OAAA,aAAa,CAAC,SAAS,EAAvB,CAAuB,CAAC,CAAC;gBACzF,0FAA0F;gBAC1F,2BAA2B;gBAC3B,IAAI,CAAC,cAAc,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE;oBACrD,sBAAO;iBACR;gBAED,cAAc,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;;;;KAC9D;IACH,6BAAC;AAAD,CAAC,AAzBD,IAyBC;AAzBY,wDAAsB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserStatusTableWatcher.d.ts","sourceRoot":"","sources":["../../../src/authentication/UserStatusTableWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,IAAI,EAAU,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"UserStatusTableWatcher.d.ts","sourceRoot":"","sources":["../../../src/authentication/UserStatusTableWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAiB,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,IAAI,EAAU,MAAM,iBAAiB,CAAC;AAI/C;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,YAAW,YAAY,CAAC,IAAI,CAAC;IAC/D,OAAO,CAAC,MAAM,CAA+C;IAE7D,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC;IAId,WAAW,CAAC,CAAC,SAAS,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CA8BrH"}
|
|
@@ -40,6 +40,7 @@ exports.UserStatusTableWatcher = void 0;
|
|
|
40
40
|
var db_1 = require("@proteinjs/db");
|
|
41
41
|
var user_1 = require("@proteinjs/user");
|
|
42
42
|
var logger_1 = require("@proteinjs/logger");
|
|
43
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
43
44
|
/**
|
|
44
45
|
* The one owner of "deactivated ⇒ sessions die": any user-table update writing
|
|
45
46
|
* `status: 'deactivated'` deletes the account's session rows (SocketIOSessionWatcher kicks the
|
|
@@ -95,7 +96,7 @@ var UserStatusTableWatcher = /** @class */ (function () {
|
|
|
95
96
|
if (deletedSessions > 0) {
|
|
96
97
|
this.logger.info({
|
|
97
98
|
message: "Deactivation killed sessions",
|
|
98
|
-
obj: {
|
|
99
|
+
obj: { account: new util_node_1.RequestDigests().account(user.email), sessions: deletedSessions },
|
|
99
100
|
});
|
|
100
101
|
}
|
|
101
102
|
return [2 /*return*/];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserStatusTableWatcher.js","sourceRoot":"","sources":["../../../src/authentication/UserStatusTableWatcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAAiF;AACjF,wCAA+C;AAC/C,4CAA2C;
|
|
1
|
+
{"version":3,"file":"UserStatusTableWatcher.js","sourceRoot":"","sources":["../../../src/authentication/UserStatusTableWatcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAAiF;AACjF,wCAA+C;AAC/C,4CAA2C;AAC3C,kDAAsD;AAEtD;;;;;;;;;GASG;AACH;IAAA;QACU,WAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAwC/D,CAAC;IAtCC,qCAAI,GAAJ;QACE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,sCAAK,GAAL;QACE,OAAO,aAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAEK,4CAAW,GAAjB,UAAkC,iBAAyB,EAAE,MAAkB,EAAE,EAAmB;;;;;;;wBAClG,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa,IAAI,iBAAiB,KAAK,CAAC,EAAE;4BAC9D,sBAAO;yBACR;wBAED,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;4BACd,yFAAyF;4BACzF,sFAAsF;4BACtF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gCAChB,OAAO,EAAE,kIAA6H;6BACvI,CAAC,CAAC;4BACH,sBAAO;yBACR;wBAEK,EAAE,GAAG,IAAA,kBAAa,GAAE,CAAC;wBAC3B,qBAAM,EAAE,CAAC,cAAc,CAAC;;;;gDACT,qBAAM,EAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,EAAA;;4CAAnD,IAAI,GAAG,SAA4C;4CACzD,IAAI,CAAC,IAAI,EAAE;gDACT,sBAAO,CAAC,mEAAmE;6CAC5E;4CAEuB,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAA;;4CAA5E,eAAe,GAAG,SAA0D;4CAClF,IAAI,eAAe,GAAG,CAAC,EAAE;gDACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;oDACf,OAAO,EAAE,8BAA8B;oDACvC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,0BAAc,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE;iDACtF,CAAC,CAAC;6CACJ;;;;iCACF,CAAC,EAAA;;wBAbF,SAaE,CAAC;;;;;KACJ;IACH,6BAAC;AAAD,CAAC,AAzCD,IAyCC;AAzCY,wDAAsB"}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
|
+
import { User } from '@proteinjs/user';
|
|
1
2
|
export declare function createAuthentication(defaultAdminCredentials?: {
|
|
2
3
|
username: string;
|
|
3
4
|
password: string;
|
|
4
5
|
}): typeof authenticate;
|
|
5
6
|
export declare function authenticate(email: string, password: string): Promise<true | string>;
|
|
7
|
+
/**
|
|
8
|
+
* Looks the account up and verifies the password — the cost every refusal pays, whether or not
|
|
9
|
+
* the address has an account: with none, the password is verified against a stand-in of the
|
|
10
|
+
* same cost (`PasswordHasher.verifyAgainstNothing`), so a refusal's timing says nothing about
|
|
11
|
+
* the address; a human row still in the legacy sha256 format (verified in microseconds) pays the
|
|
12
|
+
* stand-in too, so a refusal's timing says nothing about whether the account has signed in since
|
|
13
|
+
* the format changed either. The login door also runs it on a throttled try and discards the
|
|
14
|
+
* verdict, so a throttled answer takes as long as a refused password. No side effects (no
|
|
15
|
+
* rehash, no log).
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkPassword(email: string, password: string): Promise<{
|
|
18
|
+
user?: User;
|
|
19
|
+
matches: boolean;
|
|
20
|
+
}>;
|
|
6
21
|
//# sourceMappingURL=authenticate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../../src/authentication/authenticate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authenticate.d.ts","sourceRoot":"","sources":["../../../src/authentication/authenticate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAU,MAAM,iBAAiB,CAAC;AAM/C,wBAAgB,oBAAoB,CAAC,uBAAuB,CAAC,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,uBAMpG;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CA8C1F;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAc/G"}
|
|
@@ -36,10 +36,11 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.authenticate = exports.createAuthentication = void 0;
|
|
39
|
+
exports.checkPassword = exports.authenticate = exports.createAuthentication = void 0;
|
|
40
40
|
var db_1 = require("@proteinjs/db");
|
|
41
41
|
var user_1 = require("@proteinjs/user");
|
|
42
42
|
var logger_1 = require("@proteinjs/logger");
|
|
43
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
43
44
|
var DefaultAdminCredentials_1 = require("./DefaultAdminCredentials");
|
|
44
45
|
var PasswordHasher_1 = require("./PasswordHasher");
|
|
45
46
|
function createAuthentication(defaultAdminCredentials) {
|
|
@@ -51,7 +52,7 @@ function createAuthentication(defaultAdminCredentials) {
|
|
|
51
52
|
exports.createAuthentication = createAuthentication;
|
|
52
53
|
function authenticate(email, password) {
|
|
53
54
|
return __awaiter(this, void 0, void 0, function () {
|
|
54
|
-
var logger, defaultAdminCredentials,
|
|
55
|
+
var logger, defaultAdminCredentials, _a, user, matches, db, hasher, mode, _b, _c, _d;
|
|
55
56
|
var _e;
|
|
56
57
|
return __generator(this, function (_f) {
|
|
57
58
|
switch (_f.label) {
|
|
@@ -64,32 +65,25 @@ function authenticate(email, password) {
|
|
|
64
65
|
logger.info({ message: 'Authenitcated default admin user' });
|
|
65
66
|
return [2 /*return*/, true];
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
return [4 /*yield*/, db.get(user_1.tables.User, { email: email.toLowerCase() })];
|
|
68
|
+
return [4 /*yield*/, checkPassword(email, password)];
|
|
69
69
|
case 1:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
_a = !user;
|
|
73
|
-
if (_a) return [3 /*break*/, 3];
|
|
74
|
-
return [4 /*yield*/, hasher.verify(user.password, password)];
|
|
75
|
-
case 2:
|
|
76
|
-
_a = !(_f.sent());
|
|
77
|
-
_f.label = 3;
|
|
78
|
-
case 3:
|
|
79
|
-
if (_a) {
|
|
70
|
+
_a = _f.sent(), user = _a.user, matches = _a.matches;
|
|
71
|
+
if (!user || !matches) {
|
|
80
72
|
return [2 /*return*/, 'User name or password incorrect'];
|
|
81
73
|
}
|
|
74
|
+
db = (0, db_1.getDbAsSystem)();
|
|
75
|
+
hasher = new PasswordHasher_1.PasswordHasher();
|
|
82
76
|
mode = user.isLoadedFromSource === true ? 'machine' : 'human';
|
|
83
|
-
if (!hasher.needsRehash(user.password, mode)) return [3 /*break*/,
|
|
77
|
+
if (!hasher.needsRehash(user.password, mode)) return [3 /*break*/, 4];
|
|
84
78
|
_c = (_b = db).update;
|
|
85
79
|
_d = [user_1.tables.User];
|
|
86
80
|
_e = { id: user.id };
|
|
87
81
|
return [4 /*yield*/, hasher.hash(password)];
|
|
88
|
-
case
|
|
89
|
-
case
|
|
82
|
+
case 2: return [4 /*yield*/, _c.apply(_b, _d.concat([(_e.password = _f.sent(), _e)]))];
|
|
83
|
+
case 3:
|
|
90
84
|
_f.sent();
|
|
91
|
-
_f.label =
|
|
92
|
-
case
|
|
85
|
+
_f.label = 4;
|
|
86
|
+
case 4:
|
|
93
87
|
// Deactivated accounts are refused a new session even with correct credentials; the session
|
|
94
88
|
// side of the same gate lives in userCache (deactivated sessions resolve as guest).
|
|
95
89
|
if (user.status === 'deactivated') {
|
|
@@ -100,7 +94,10 @@ function authenticate(email, password) {
|
|
|
100
94
|
if (user.deleteRequestedAt != null) {
|
|
101
95
|
return [2 /*return*/, true];
|
|
102
96
|
}
|
|
103
|
-
logger.warn({
|
|
97
|
+
logger.warn({
|
|
98
|
+
message: 'Refused login for deactivated account',
|
|
99
|
+
obj: { account: new util_node_1.RequestDigests().account(email) },
|
|
100
|
+
});
|
|
104
101
|
return [2 /*return*/, 'This account has been deactivated'];
|
|
105
102
|
}
|
|
106
103
|
return [2 /*return*/, true];
|
|
@@ -109,4 +106,42 @@ function authenticate(email, password) {
|
|
|
109
106
|
});
|
|
110
107
|
}
|
|
111
108
|
exports.authenticate = authenticate;
|
|
109
|
+
/**
|
|
110
|
+
* Looks the account up and verifies the password — the cost every refusal pays, whether or not
|
|
111
|
+
* the address has an account: with none, the password is verified against a stand-in of the
|
|
112
|
+
* same cost (`PasswordHasher.verifyAgainstNothing`), so a refusal's timing says nothing about
|
|
113
|
+
* the address; a human row still in the legacy sha256 format (verified in microseconds) pays the
|
|
114
|
+
* stand-in too, so a refusal's timing says nothing about whether the account has signed in since
|
|
115
|
+
* the format changed either. The login door also runs it on a throttled try and discards the
|
|
116
|
+
* verdict, so a throttled answer takes as long as a refused password. No side effects (no
|
|
117
|
+
* rehash, no log).
|
|
118
|
+
*/
|
|
119
|
+
function checkPassword(email, password) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
121
|
+
var user, hasher, matches;
|
|
122
|
+
var _a;
|
|
123
|
+
return __generator(this, function (_b) {
|
|
124
|
+
switch (_b.label) {
|
|
125
|
+
case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { email: email.toLowerCase() })];
|
|
126
|
+
case 1:
|
|
127
|
+
user = _b.sent();
|
|
128
|
+
hasher = new PasswordHasher_1.PasswordHasher();
|
|
129
|
+
if (!!user) return [3 /*break*/, 3];
|
|
130
|
+
_a = {};
|
|
131
|
+
return [4 /*yield*/, hasher.verifyAgainstNothing(password)];
|
|
132
|
+
case 2: return [2 /*return*/, (_a.matches = _b.sent(), _a)];
|
|
133
|
+
case 3: return [4 /*yield*/, hasher.verify(user.password, password)];
|
|
134
|
+
case 4:
|
|
135
|
+
matches = _b.sent();
|
|
136
|
+
if (!hasher.needsRehash(user.password, user.isLoadedFromSource === true ? 'machine' : 'human')) return [3 /*break*/, 6];
|
|
137
|
+
return [4 /*yield*/, hasher.verifyAgainstNothing(password)];
|
|
138
|
+
case 5:
|
|
139
|
+
_b.sent();
|
|
140
|
+
_b.label = 6;
|
|
141
|
+
case 6: return [2 /*return*/, { user: user, matches: matches }];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
exports.checkPassword = checkPassword;
|
|
112
147
|
//# sourceMappingURL=authenticate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../../src/authentication/authenticate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA8C;AAC9C,
|
|
1
|
+
{"version":3,"file":"authenticate.js","sourceRoot":"","sources":["../../../src/authentication/authenticate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userCache.d.ts","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"userCache.d.ts","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,OAAO,EAAE,IAAI,EAA6C,MAAM,iBAAiB,CAAC;AAKlF;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,IAAI,CA8C5C,CAAC"}
|
|
@@ -43,6 +43,7 @@ exports.userCache = void 0;
|
|
|
43
43
|
var moment_1 = __importDefault(require("moment"));
|
|
44
44
|
var db_1 = require("@proteinjs/db");
|
|
45
45
|
var logger_1 = require("@proteinjs/logger");
|
|
46
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
46
47
|
var user_1 = require("@proteinjs/user");
|
|
47
48
|
var DefaultAdminCredentials_1 = require("../authentication/DefaultAdminCredentials");
|
|
48
49
|
var logger = new logger_1.Logger({ name: 'userCache' });
|
|
@@ -87,7 +88,7 @@ exports.userCache = {
|
|
|
87
88
|
// account is deactivated — every request runs as the unauthenticated guest.
|
|
88
89
|
logger.warn({
|
|
89
90
|
message: "Session references a deactivated account; resolving as unauthenticated",
|
|
90
|
-
obj: { sessionId: sessionId,
|
|
91
|
+
obj: { sessionId: sessionId, account: new util_node_1.RequestDigests().account(userEmail) },
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
else if (accountUser) {
|
|
@@ -101,7 +102,7 @@ exports.userCache = {
|
|
|
101
102
|
// build as an unhandled rejection and downs the process.
|
|
102
103
|
logger.warn({
|
|
103
104
|
message: "Session references an account that does not exist; resolving as unauthenticated",
|
|
104
|
-
obj: { sessionId: sessionId,
|
|
105
|
+
obj: { sessionId: sessionId, account: new util_node_1.RequestDigests().account(userEmail) },
|
|
105
106
|
});
|
|
106
107
|
}
|
|
107
108
|
_a.label = 3;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userCache.js","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,oCAA8C;AAC9C,4CAA2C;AAC3C,wCAAkF;AAClF,qFAAoF;AAEpF,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAEjD;;;;;;;;GAQG;AACU,QAAA,SAAS,GAA2B;IAC/C,GAAG,EAAE,6BAAsB;IAC3B,MAAM,EAAE,UAAO,SAAiB,EAAE,SAAiB;;;;;oBAC7C,IAAI,GAAG,gBAAS,CAAC;yBACjB,SAAS,EAAT,wBAAS;oBACL,gBAAgB,GAAG,iDAAuB,CAAC,cAAc,EAAE,CAAC;yBAC9D,CAAA,gBAAgB,IAAI,SAAS,IAAI,gBAAgB,CAAC,QAAQ,CAAA,EAA1D,wBAA0D;oBACtD,SAAS,GAAS;wBACtB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,gBAAgB,CAAC,QAAQ;wBAChC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;wBACnC,aAAa,EAAE,IAAI;wBACnB,KAAK,EAAE,CAAC,OAAO,CAAC;wBAChB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,EAAE,EAAE,OAAO;qBACZ,CAAC;oBACF,IAAI,GAAG,SAAS,CAAC;;wBAEG,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,EAAA;;oBAAxF,WAAW,GAAG,SAA0E;oBAC9F,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,aAAa,EAAE;wBACvD,sFAAsF;wBACtF,iFAAiF;wBACjF,4EAA4E;wBAC5E,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,wEAAwE;4BACjF,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"userCache.js","sourceRoot":"","sources":["../../../src/authorization/userCache.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B,oCAA8C;AAC9C,4CAA2C;AAC3C,kDAAsD;AACtD,wCAAkF;AAClF,qFAAoF;AAEpF,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAEjD;;;;;;;;GAQG;AACU,QAAA,SAAS,GAA2B;IAC/C,GAAG,EAAE,6BAAsB;IAC3B,MAAM,EAAE,UAAO,SAAiB,EAAE,SAAiB;;;;;oBAC7C,IAAI,GAAG,gBAAS,CAAC;yBACjB,SAAS,EAAT,wBAAS;oBACL,gBAAgB,GAAG,iDAAuB,CAAC,cAAc,EAAE,CAAC;yBAC9D,CAAA,gBAAgB,IAAI,SAAS,IAAI,gBAAgB,CAAC,QAAQ,CAAA,EAA1D,wBAA0D;oBACtD,SAAS,GAAS;wBACtB,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,gBAAgB,CAAC,QAAQ;wBAChC,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;wBACnC,aAAa,EAAE,IAAI;wBACnB,KAAK,EAAE,CAAC,OAAO,CAAC;wBAChB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,OAAO,EAAE,IAAA,gBAAM,GAAE;wBACjB,EAAE,EAAE,OAAO;qBACZ,CAAC;oBACF,IAAI,GAAG,SAAS,CAAC;;wBAEG,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,EAAA;;oBAAxF,WAAW,GAAG,SAA0E;oBAC9F,IAAI,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,aAAa,EAAE;wBACvD,sFAAsF;wBACtF,iFAAiF;wBACjF,4EAA4E;wBAC5E,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,wEAAwE;4BACjF,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,OAAO,EAAE,IAAI,0BAAc,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;yBACrE,CAAC,CAAC;qBACJ;yBAAM,IAAI,WAAW,EAAE;wBACtB,OAAQ,WAAmB,CAAC,UAAU,CAAC,CAAC;wBACxC,IAAI,GAAG,WAAW,CAAC;qBACpB;yBAAM;wBACL,0FAA0F;wBAC1F,+EAA+E;wBAC/E,sFAAsF;wBACtF,yDAAyD;wBACzD,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,iFAAiF;4BAC1F,GAAG,EAAE,EAAE,SAAS,WAAA,EAAE,OAAO,EAAE,IAAI,0BAAc,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;yBACrE,CAAC,CAAC;qBACJ;;wBAIL,sBAAO,IAAI,EAAC;;;SACb;CACF,CAAC"}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"devLogin.d.ts","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAe9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,QAAQ,EAAE,KAuEtB,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_node_1 = require("@proteinjs/util-node");
|
|
41
42
|
var util_1 = require("@proteinjs/util");
|
|
42
43
|
var establishSession_1 = require("../authentication/establishSession");
|
|
43
44
|
var Roles_1 = require("../services/Roles");
|
|
@@ -97,7 +98,7 @@ exports.devLogin = {
|
|
|
97
98
|
path: '/dev/login',
|
|
98
99
|
method: 'get',
|
|
99
100
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
100
|
-
var envEmail, email, emailParam, requested, creation, bootstrapEmail, outcome, bootstrapRoles, outcome;
|
|
101
|
+
var envEmail, email, emailParam, requested, digests, creation, error_1, bootstrapEmail, outcome, bootstrapRoles, outcome;
|
|
101
102
|
var _a, _b, _c;
|
|
102
103
|
return __generator(this, function (_d) {
|
|
103
104
|
switch (_d.label) {
|
|
@@ -125,6 +126,10 @@ exports.devLogin = {
|
|
|
125
126
|
email = requested;
|
|
126
127
|
}
|
|
127
128
|
email = email.toLowerCase();
|
|
129
|
+
digests = new util_node_1.RequestDigests();
|
|
130
|
+
_d.label = 1;
|
|
131
|
+
case 1:
|
|
132
|
+
_d.trys.push([1, 3, , 4]);
|
|
128
133
|
return [4 /*yield*/, new Signup_1.Signup().createAccount({
|
|
129
134
|
name: email.slice(0, email.indexOf('@')),
|
|
130
135
|
email: email,
|
|
@@ -132,35 +137,45 @@ exports.devLogin = {
|
|
|
132
137
|
emailVerified: false,
|
|
133
138
|
invitedBy: null,
|
|
134
139
|
})];
|
|
135
|
-
case
|
|
140
|
+
case 2:
|
|
136
141
|
creation = _d.sent();
|
|
142
|
+
return [3 /*break*/, 4];
|
|
143
|
+
case 3:
|
|
144
|
+
error_1 = _d.sent();
|
|
145
|
+
// createAccount refuses in plain words (an address a machine-account declaration owns); the
|
|
146
|
+
// dev door answers the way its other refusals do — the words, no session, no row.
|
|
147
|
+
response
|
|
148
|
+
.status(400)
|
|
149
|
+
.send("/dev/login: ".concat(error_1 instanceof Error ? error_1.message : 'the account could not be created'));
|
|
150
|
+
return [2 /*return*/];
|
|
151
|
+
case 4:
|
|
137
152
|
if (creation === 'created') {
|
|
138
|
-
logger.info({ message: 'Dev auto-login created missing test account', obj: {
|
|
153
|
+
logger.info({ message: 'Dev auto-login created missing test account', obj: { account: digests.account(email) } });
|
|
139
154
|
}
|
|
140
155
|
bootstrapEmail = ((_c = process.env.DEV_BOOTSTRAP_ADMIN_EMAIL) !== null && _c !== void 0 ? _c : '').trim().toLowerCase();
|
|
141
|
-
if (!(bootstrapEmail && email === bootstrapEmail)) return [3 /*break*/,
|
|
156
|
+
if (!(bootstrapEmail && email === bootstrapEmail)) return [3 /*break*/, 6];
|
|
142
157
|
return [4 /*yield*/, new Roles_1.Roles().bootstrapAdmin(email)];
|
|
143
|
-
case
|
|
158
|
+
case 5:
|
|
144
159
|
outcome = _d.sent();
|
|
145
|
-
logger.info({ message: "Dev bootstrap admin door: ".concat(outcome), obj: {
|
|
146
|
-
_d.label =
|
|
147
|
-
case
|
|
160
|
+
logger.info({ message: "Dev bootstrap admin door: ".concat(outcome), obj: { account: digests.account(email) } });
|
|
161
|
+
_d.label = 6;
|
|
162
|
+
case 6:
|
|
148
163
|
bootstrapRoles = DevBootstrapRoles_1.DevBootstrapRoles.rolesFor(email);
|
|
149
|
-
if (!(bootstrapRoles.length > 0)) return [3 /*break*/,
|
|
164
|
+
if (!(bootstrapRoles.length > 0)) return [3 /*break*/, 8];
|
|
150
165
|
return [4 /*yield*/, new Roles_1.Roles().bootstrapRoles(email, bootstrapRoles)];
|
|
151
|
-
case
|
|
166
|
+
case 7:
|
|
152
167
|
outcome = _d.sent();
|
|
153
168
|
logger.info({ message: DevBootstrapRoles_1.DevBootstrapRoles.markerLine(email, outcome) });
|
|
154
|
-
_d.label =
|
|
155
|
-
case
|
|
169
|
+
_d.label = 8;
|
|
170
|
+
case 8:
|
|
156
171
|
// establishSession commits the session row before the redirect — the redirected GET / must
|
|
157
172
|
// never read the store ahead of the write (observed: first /dev/login load landed on /login).
|
|
158
173
|
return [4 /*yield*/, (0, establishSession_1.establishSession)(request, email)];
|
|
159
|
-
case
|
|
174
|
+
case 9:
|
|
160
175
|
// establishSession commits the session row before the redirect — the redirected GET / must
|
|
161
176
|
// never read the store ahead of the write (observed: first /dev/login load landed on /login).
|
|
162
177
|
_d.sent();
|
|
163
|
-
logger.info({ message: 'Dev auto-login session established', obj: {
|
|
178
|
+
logger.info({ message: 'Dev auto-login session established', obj: { account: digests.account(email) } });
|
|
164
179
|
response.redirect('/');
|
|
165
180
|
return [2 /*return*/];
|
|
166
181
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAC3C,wCAA6C;AAC7C,uEAAsE;AACtE,2CAA0C;AAC1C,6CAA4C;AAC5C,yDAAwD;AAExD,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;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;
|
|
1
|
+
{"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,10 @@ import { Route } from '@proteinjs/server-api';
|
|
|
8
8
|
* The token itself never reaches the log. A request that carries no body at all is refused like
|
|
9
9
|
* one that carries a blank password.
|
|
10
10
|
*
|
|
11
|
+
* A redeemed link also opens the account's sign-in window again (`SignInThrottle`): the person
|
|
12
|
+
* just proved the mailbox, so a reset made while wrong guesses held the door shut lets the new
|
|
13
|
+
* password in at once instead of waiting the window out.
|
|
14
|
+
*
|
|
11
15
|
* @bodyParam {string} token - The password reset token.
|
|
12
16
|
* @bodyParam {string} newPassword - The new password for the user.
|
|
13
17
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executePasswordReset.d.ts","sourceRoot":"","sources":["../../../src/routes/executePasswordReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"executePasswordReset.d.ts","sourceRoot":"","sources":["../../../src/routes/executePasswordReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQ9C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAyClC,CAAC"}
|
|
@@ -39,8 +39,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.executePasswordReset = void 0;
|
|
40
40
|
var user_1 = require("@proteinjs/user");
|
|
41
41
|
var logger_1 = require("@proteinjs/logger");
|
|
42
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
42
43
|
var PasswordHasher_1 = require("../authentication/PasswordHasher");
|
|
43
44
|
var PasswordResetToken_1 = require("../authentication/PasswordResetToken");
|
|
45
|
+
var SignInThrottle_1 = require("../throttle/SignInThrottle");
|
|
44
46
|
/**
|
|
45
47
|
* Route handler for executing a password reset.
|
|
46
48
|
*
|
|
@@ -50,6 +52,10 @@ var PasswordResetToken_1 = require("../authentication/PasswordResetToken");
|
|
|
50
52
|
* The token itself never reaches the log. A request that carries no body at all is refused like
|
|
51
53
|
* one that carries a blank password.
|
|
52
54
|
*
|
|
55
|
+
* A redeemed link also opens the account's sign-in window again (`SignInThrottle`): the person
|
|
56
|
+
* just proved the mailbox, so a reset made while wrong guesses held the door shut lets the new
|
|
57
|
+
* password in at once instead of waiting the window out.
|
|
58
|
+
*
|
|
53
59
|
* @bodyParam {string} token - The password reset token.
|
|
54
60
|
* @bodyParam {string} newPassword - The new password for the user.
|
|
55
61
|
*/
|
|
@@ -57,12 +63,13 @@ exports.executePasswordReset = {
|
|
|
57
63
|
path: user_1.routes.executePasswordReset.path,
|
|
58
64
|
method: user_1.routes.executePasswordReset.method,
|
|
59
65
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
60
|
-
var logger, _a, token, newPassword, resetToken, resolution, user, hashedPassword;
|
|
66
|
+
var logger, digests, _a, token, newPassword, resetToken, resolution, user, hashedPassword;
|
|
61
67
|
var _b;
|
|
62
68
|
return __generator(this, function (_c) {
|
|
63
69
|
switch (_c.label) {
|
|
64
70
|
case 0:
|
|
65
71
|
logger = new logger_1.Logger({ name: 'executePasswordReset' });
|
|
72
|
+
digests = new util_node_1.RequestDigests();
|
|
66
73
|
_a = (_b = request.body) !== null && _b !== void 0 ? _b : {}, token = _a.token, newPassword = _a.newPassword;
|
|
67
74
|
if (typeof newPassword !== 'string' || newPassword.length === 0) {
|
|
68
75
|
response.status(400).send({ error: 'New password cannot be blank' });
|
|
@@ -81,7 +88,7 @@ exports.executePasswordReset = {
|
|
|
81
88
|
return [2 /*return*/];
|
|
82
89
|
}
|
|
83
90
|
if (resolution.status === 'expired') {
|
|
84
|
-
logger.info({ message: "Expired reset token used", obj: {
|
|
91
|
+
logger.info({ message: "Expired reset token used", obj: { account: digests.account(resolution.user.email) } });
|
|
85
92
|
response.status(400).send({ error: 'Reset token has expired' });
|
|
86
93
|
return [2 /*return*/];
|
|
87
94
|
}
|
|
@@ -92,11 +99,12 @@ exports.executePasswordReset = {
|
|
|
92
99
|
return [4 /*yield*/, resetToken.redeem(user, resolution.token, hashedPassword)];
|
|
93
100
|
case 3:
|
|
94
101
|
if (!(_c.sent())) {
|
|
95
|
-
logger.info({ message: "Reset token already redeemed", obj: {
|
|
102
|
+
logger.info({ message: "Reset token already redeemed", obj: { account: digests.account(user.email) } });
|
|
96
103
|
response.status(400).send({ error: 'Invalid or expired reset token' });
|
|
97
104
|
return [2 /*return*/];
|
|
98
105
|
}
|
|
99
|
-
|
|
106
|
+
SignInThrottle_1.signInThrottle.recordSuccess(digests.account(user.email));
|
|
107
|
+
logger.info({ message: "Password successfully reset", obj: { account: digests.account(user.email) } });
|
|
100
108
|
response.send({ message: 'Password has been successfully reset' });
|
|
101
109
|
return [2 /*return*/];
|
|
102
110
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executePasswordReset.js","sourceRoot":"","sources":["../../../src/routes/executePasswordReset.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAyC;AACzC,4CAA2C;AAC3C,mEAAkE;AAClE,2EAA0E;
|
|
1
|
+
{"version":3,"file":"executePasswordReset.js","sourceRoot":"","sources":["../../../src/routes/executePasswordReset.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,13 @@ import { Route } from '@proteinjs/server-api';
|
|
|
6
6
|
* its expiry on the user row — and mails the token to the account as a reset link. The token is
|
|
7
7
|
* withdrawn again when the mail fails to send.
|
|
8
8
|
*
|
|
9
|
+
* ONE ANSWER: every request with an address is answered `ONE_ANSWER` — BEFORE the address is
|
|
10
|
+
* looked up — whether it has an account, is throttled (`PasswordResetThrottle`: per client and
|
|
11
|
+
* per address), is inside the account's five-minute gap, or its mail fails; so neither the
|
|
12
|
+
* words, the status nor the timing say whether an address has an account. The work runs after
|
|
13
|
+
* the answer. Every request is one outcome line carrying the account digest and the coarse IP
|
|
14
|
+
* hash (`RequestDigests`) — never the address.
|
|
15
|
+
*
|
|
9
16
|
* Requires an implementation of `DefaultPasswordResetEmailConfigFactory` to build the password reset email with.
|
|
10
17
|
*
|
|
11
18
|
* @bodyParam {string} email - The email address of the user requesting a password reset.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initiatePasswordReset.d.ts","sourceRoot":"","sources":["../../../src/routes/initiatePasswordReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"initiatePasswordReset.d.ts","sourceRoot":"","sources":["../../../src/routes/initiatePasswordReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAoB9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAoEnC,CAAC"}
|