@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
|
@@ -54,9 +54,17 @@ exports.initiatePasswordReset = void 0;
|
|
|
54
54
|
var db_1 = require("@proteinjs/db");
|
|
55
55
|
var user_1 = require("@proteinjs/user");
|
|
56
56
|
var logger_1 = require("@proteinjs/logger");
|
|
57
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
57
58
|
var moment_1 = __importDefault(require("moment"));
|
|
58
59
|
var email_server_1 = require("@proteinjs/email-server");
|
|
59
60
|
var PasswordResetToken_1 = require("../authentication/PasswordResetToken");
|
|
61
|
+
var ClientAddress_1 = require("../throttle/ClientAddress");
|
|
62
|
+
var PasswordResetThrottle_1 = require("../throttle/PasswordResetThrottle");
|
|
63
|
+
/**
|
|
64
|
+
* The door's one answer: the same words for an address with an account or without, inside or
|
|
65
|
+
* past a window, mailed or not — the page shows exactly this sentence.
|
|
66
|
+
*/
|
|
67
|
+
var ONE_ANSWER = { message: 'If that address has an account, a reset link is on its way.' };
|
|
60
68
|
/**
|
|
61
69
|
* Route for initiating a password reset process.
|
|
62
70
|
*
|
|
@@ -64,6 +72,13 @@ var PasswordResetToken_1 = require("../authentication/PasswordResetToken");
|
|
|
64
72
|
* its expiry on the user row — and mails the token to the account as a reset link. The token is
|
|
65
73
|
* withdrawn again when the mail fails to send.
|
|
66
74
|
*
|
|
75
|
+
* ONE ANSWER: every request with an address is answered `ONE_ANSWER` — BEFORE the address is
|
|
76
|
+
* looked up — whether it has an account, is throttled (`PasswordResetThrottle`: per client and
|
|
77
|
+
* per address), is inside the account's five-minute gap, or its mail fails; so neither the
|
|
78
|
+
* words, the status nor the timing say whether an address has an account. The work runs after
|
|
79
|
+
* the answer. Every request is one outcome line carrying the account digest and the coarse IP
|
|
80
|
+
* hash (`RequestDigests`) — never the address.
|
|
81
|
+
*
|
|
67
82
|
* Requires an implementation of `DefaultPasswordResetEmailConfigFactory` to build the password reset email with.
|
|
68
83
|
*
|
|
69
84
|
* @bodyParam {string} email - The email address of the user requesting a password reset.
|
|
@@ -75,7 +90,7 @@ exports.initiatePasswordReset = {
|
|
|
75
90
|
path: user_1.routes.initiatePasswordReset.path,
|
|
76
91
|
method: user_1.routes.initiatePasswordReset.method,
|
|
77
92
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
78
|
-
var logger, requestedEmail, email, db,
|
|
93
|
+
var logger, requestedEmail, digests, fields, window, email, db, user, resetToken, mintedAt, emailSender, defaultConfigFactory, passwordResetToken, config, _a, text, html, error_1;
|
|
79
94
|
var _b, _c;
|
|
80
95
|
return __generator(this, function (_d) {
|
|
81
96
|
switch (_d.label) {
|
|
@@ -86,23 +101,27 @@ exports.initiatePasswordReset = {
|
|
|
86
101
|
response.status(400).send({ error: 'Email cannot be blank' });
|
|
87
102
|
return [2 /*return*/];
|
|
88
103
|
}
|
|
104
|
+
digests = new util_node_1.RequestDigests();
|
|
105
|
+
fields = { account: digests.account(requestedEmail), ip: digests.coarseIp(new ClientAddress_1.ClientAddress().of(request)) };
|
|
106
|
+
window = PasswordResetThrottle_1.passwordResetThrottle.admit(fields.ip, fields.account);
|
|
107
|
+
response.send(ONE_ANSWER);
|
|
108
|
+
if (window) {
|
|
109
|
+
logger.warn({ message: "Password reset throttled", obj: __assign(__assign({}, fields), { window: window }) });
|
|
110
|
+
return [2 /*return*/];
|
|
111
|
+
}
|
|
89
112
|
email = requestedEmail.toLowerCase();
|
|
90
113
|
db = (0, db_1.getDbAsSystem)();
|
|
91
|
-
genericResponse = { message: 'If an account with that email exists, we have sent a password reset link.' };
|
|
92
114
|
return [4 /*yield*/, db.get(user_1.tables.User, { email: email })];
|
|
93
115
|
case 1:
|
|
94
116
|
user = _d.sent();
|
|
95
117
|
if (!user) {
|
|
96
|
-
logger.info({ message: "Password reset requested for non-existent user", obj:
|
|
97
|
-
// Don't reveal that the user doesn't exist
|
|
98
|
-
response.send(genericResponse);
|
|
118
|
+
logger.info({ message: "Password reset requested for non-existent user", obj: fields });
|
|
99
119
|
return [2 /*return*/];
|
|
100
120
|
}
|
|
101
121
|
resetToken = new PasswordResetToken_1.PasswordResetToken();
|
|
102
122
|
mintedAt = resetToken.mintedAt(user);
|
|
103
123
|
if (mintedAt && (0, moment_1.default)().diff(mintedAt, 'minutes') < 5) {
|
|
104
|
-
logger.info({ message: "Password reset requested too soon for user", obj:
|
|
105
|
-
response.send(genericResponse);
|
|
124
|
+
logger.info({ message: "Password reset requested too soon for user", obj: fields });
|
|
106
125
|
return [2 /*return*/];
|
|
107
126
|
}
|
|
108
127
|
emailSender = new email_server_1.EmailSender();
|
|
@@ -123,17 +142,16 @@ exports.initiatePasswordReset = {
|
|
|
123
142
|
case 4:
|
|
124
143
|
// Send email containing a reset link
|
|
125
144
|
_d.sent();
|
|
126
|
-
|
|
145
|
+
logger.info({ message: "Password reset link mailed", obj: fields });
|
|
127
146
|
return [3 /*break*/, 7];
|
|
128
147
|
case 5:
|
|
129
148
|
error_1 = _d.sent();
|
|
130
|
-
logger.error({ message: "Failed to send password reset email", obj:
|
|
149
|
+
logger.error({ message: "Failed to send password reset email", obj: fields, error: error_1 });
|
|
131
150
|
// The link never reached the account: withdraw the token so asking again is not throttled
|
|
132
151
|
return [4 /*yield*/, resetToken.revoke(user, passwordResetToken)];
|
|
133
152
|
case 6:
|
|
134
153
|
// The link never reached the account: withdraw the token so asking again is not throttled
|
|
135
154
|
_d.sent();
|
|
136
|
-
response.status(500).send({ error: 'Failed to send password reset email. Please try again later.' });
|
|
137
155
|
return [3 /*break*/, 7];
|
|
138
156
|
case 7: return [2 /*return*/];
|
|
139
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initiatePasswordReset.js","sourceRoot":"","sources":["../../../src/routes/initiatePasswordReset.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oCAA8C;AAC9C,wCAA2D;AAC3D,4CAA2C;AAC3C,kDAA4B;AAC5B,wDAGiC;AACjC,2EAA0E;AAE1E
|
|
1
|
+
{"version":3,"file":"initiatePasswordReset.js","sourceRoot":"","sources":["../../../src/routes/initiatePasswordReset.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { Route } from '@proteinjs/server-api';
|
|
2
|
+
/**
|
|
3
|
+
* `POST /user/login`. Throttled per client and per account (`SignInThrottle`): a throttled try
|
|
4
|
+
* is told "Too many attempts. Try again in a few minutes." whether or not the address has an
|
|
5
|
+
* account, after the same password check a refusal runs (verdict discarded), so neither the
|
|
6
|
+
* words nor the timing tell. Every refusal is a "Sign-in refused" line and every throttled try
|
|
7
|
+
* its own "Sign-in throttled" line, carrying the account digest and the coarse IP hash
|
|
8
|
+
* (`RequestDigests`) — never the address.
|
|
9
|
+
*/
|
|
2
10
|
export declare const login: Route;
|
|
3
11
|
//# sourceMappingURL=login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/routes/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/routes/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAU9C;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,EAAE,KA+DnB,CAAC"}
|
package/dist/src/routes/login.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
14
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
15
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -38,41 +49,71 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
38
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
50
|
exports.login = void 0;
|
|
40
51
|
var user_1 = require("@proteinjs/user");
|
|
52
|
+
var logger_1 = require("@proteinjs/logger");
|
|
41
53
|
var authenticate_1 = require("../authentication/authenticate");
|
|
42
54
|
var establishSession_1 = require("../authentication/establishSession");
|
|
43
55
|
var AccountDeletion_1 = require("../services/AccountDeletion");
|
|
56
|
+
var ClientAddress_1 = require("../throttle/ClientAddress");
|
|
57
|
+
var RequestDigests_1 = require("../throttle/RequestDigests");
|
|
58
|
+
var SignInThrottle_1 = require("../throttle/SignInThrottle");
|
|
59
|
+
/**
|
|
60
|
+
* `POST /user/login`. Throttled per client and per account (`SignInThrottle`): a throttled try
|
|
61
|
+
* is told "Too many attempts. Try again in a few minutes." whether or not the address has an
|
|
62
|
+
* account, after the same password check a refusal runs (verdict discarded), so neither the
|
|
63
|
+
* words nor the timing tell. Every refusal is a "Sign-in refused" line and every throttled try
|
|
64
|
+
* its own "Sign-in throttled" line, carrying the account digest and the coarse IP hash
|
|
65
|
+
* (`RequestDigests`) — never the address.
|
|
66
|
+
*/
|
|
44
67
|
exports.login = {
|
|
45
68
|
path: user_1.routes.login.path,
|
|
46
69
|
method: user_1.routes.login.method,
|
|
47
70
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
48
|
-
var credentials, error, result, outcome, error_1, error;
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
var logger, credentials, email, password, digests, ip, account, fields, window, error, result, outcome, error_1, error;
|
|
72
|
+
var _a;
|
|
73
|
+
return __generator(this, function (_b) {
|
|
74
|
+
switch (_b.label) {
|
|
51
75
|
case 0:
|
|
52
|
-
|
|
53
|
-
|
|
76
|
+
logger = new logger_1.Logger({ name: 'login' });
|
|
77
|
+
credentials = (_a = request.body) !== null && _a !== void 0 ? _a : {};
|
|
78
|
+
email = typeof credentials.email === 'string' ? credentials.email : '';
|
|
79
|
+
password = typeof credentials.password === 'string' ? credentials.password : '';
|
|
80
|
+
digests = new RequestDigests_1.RequestDigests();
|
|
81
|
+
ip = digests.coarseIp(new ClientAddress_1.ClientAddress().of(request));
|
|
82
|
+
account = email ? digests.account(email) : undefined;
|
|
83
|
+
fields = account ? { account: account, ip: ip } : { ip: ip };
|
|
84
|
+
window = SignInThrottle_1.signInThrottle.admit(ip, password ? account : undefined);
|
|
85
|
+
if (!window) return [3 /*break*/, 2];
|
|
86
|
+
return [4 /*yield*/, (0, authenticate_1.checkPassword)(email, password)];
|
|
87
|
+
case 1:
|
|
88
|
+
_b.sent();
|
|
89
|
+
logger.warn({ message: 'Sign-in throttled', obj: __assign(__assign({}, fields), { window: window }) });
|
|
90
|
+
response.send({ error: SignInThrottle_1.SignInThrottle.ANSWER });
|
|
91
|
+
return [2 /*return*/];
|
|
92
|
+
case 2:
|
|
93
|
+
if (!email || !password || !account) {
|
|
54
94
|
error = "Email and password cannot be blank";
|
|
55
|
-
|
|
95
|
+
logger.info({ message: 'Sign-in refused', obj: __assign(__assign({}, fields), { reason: error }) });
|
|
56
96
|
response.send({ error: error });
|
|
57
97
|
return [2 /*return*/];
|
|
58
98
|
}
|
|
59
|
-
return [4 /*yield*/, (0, authenticate_1.authenticate)(
|
|
60
|
-
case
|
|
61
|
-
result =
|
|
99
|
+
return [4 /*yield*/, (0, authenticate_1.authenticate)(email, password)];
|
|
100
|
+
case 3:
|
|
101
|
+
result = _b.sent();
|
|
62
102
|
if (result !== true) {
|
|
63
|
-
|
|
103
|
+
logger.info({ message: 'Sign-in refused', obj: __assign(__assign({}, fields), { reason: result }) });
|
|
64
104
|
response.send({ error: result });
|
|
65
105
|
return [2 /*return*/];
|
|
66
106
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
_a.trys.push([2, 4, , 5]);
|
|
70
|
-
return [4 /*yield*/, new AccountDeletion_1.AccountDeletion().cancelPendingDeletion(credentials.email)];
|
|
71
|
-
case 3:
|
|
72
|
-
outcome = _a.sent();
|
|
73
|
-
return [3 /*break*/, 5];
|
|
107
|
+
SignInThrottle_1.signInThrottle.recordSuccess(account, ip);
|
|
108
|
+
_b.label = 4;
|
|
74
109
|
case 4:
|
|
75
|
-
|
|
110
|
+
_b.trys.push([4, 6, , 7]);
|
|
111
|
+
return [4 /*yield*/, new AccountDeletion_1.AccountDeletion().cancelPendingDeletion(email)];
|
|
112
|
+
case 5:
|
|
113
|
+
outcome = _b.sent();
|
|
114
|
+
return [3 /*break*/, 7];
|
|
115
|
+
case 6:
|
|
116
|
+
error_1 = _b.sent();
|
|
76
117
|
// Security boundary: the login response never carries internal error detail — an
|
|
77
118
|
// attacker probing emails must learn nothing from failure shapes (founder ruling
|
|
78
119
|
// 2026-08-18 after a watcher error surfaced verbatim in the login form). The real
|
|
@@ -80,16 +121,16 @@ exports.login = {
|
|
|
80
121
|
console.error('cancelPendingDeletion failed during login', error_1);
|
|
81
122
|
response.send({ error: 'Unable to log in right now. Please try again.' });
|
|
82
123
|
return [2 /*return*/];
|
|
83
|
-
case
|
|
124
|
+
case 7:
|
|
84
125
|
if (outcome === 'purging') {
|
|
85
126
|
error = 'This account is being deleted and can no longer be restored.';
|
|
86
127
|
console.error(error);
|
|
87
128
|
response.send({ error: error });
|
|
88
129
|
return [2 /*return*/];
|
|
89
130
|
}
|
|
90
|
-
return [4 /*yield*/, (0, establishSession_1.establishSession)(request,
|
|
91
|
-
case
|
|
92
|
-
|
|
131
|
+
return [4 /*yield*/, (0, establishSession_1.establishSession)(request, email)];
|
|
132
|
+
case 8:
|
|
133
|
+
_b.sent();
|
|
93
134
|
response.send({});
|
|
94
135
|
return [2 /*return*/];
|
|
95
136
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/routes/login.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/routes/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signup.d.ts","sourceRoot":"","sources":["../../../src/routes/signup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"signup.d.ts","sourceRoot":"","sources":["../../../src/routes/signup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAS9C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM,EAAE,KAgCpB,CAAC"}
|
|
@@ -38,6 +38,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.signup = void 0;
|
|
40
40
|
var logger_1 = require("@proteinjs/logger");
|
|
41
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
41
42
|
var user_1 = require("@proteinjs/user");
|
|
42
43
|
var establishSession_1 = require("../authentication/establishSession");
|
|
43
44
|
var Signup_1 = require("../services/Signup");
|
|
@@ -82,8 +83,10 @@ exports.signup = {
|
|
|
82
83
|
case 3:
|
|
83
84
|
error_1 = _b.sent();
|
|
84
85
|
// createUser throws plain-words errors deliberately (invite expired / invite required /
|
|
85
|
-
// email missing); the message is the user-facing contract, same as the RPC layer's.
|
|
86
|
-
|
|
86
|
+
// email missing); the message is the user-facing contract, same as the RPC layer's. The log
|
|
87
|
+
// gets the error through the digest door: a concurrent double sign-up's unique-index refusal
|
|
88
|
+
// names the address in the database's own words.
|
|
89
|
+
logger.error({ message: 'Signup failed', error: new util_node_1.RequestDigests().redactError(error_1) });
|
|
87
90
|
response.send({ error: error_1 instanceof Error ? error_1.message : 'Sign up failed.' });
|
|
88
91
|
return [2 /*return*/];
|
|
89
92
|
case 4:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../../src/routes/signup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAC3C,wCAAqD;AACrD,uEAAsE;AACtE,6CAA4C;AAE5C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACU,QAAA,MAAM,GAAU;IAC3B,IAAI,EAAE,aAAM,CAAC,MAAM,CAAC,IAAI;IACxB,MAAM,EAAE,aAAM,CAAC,MAAM,CAAC,MAAM;IAC5B,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,IAAI,GAA6C,MAAA,OAAO,CAAC,IAAI,mCAAI,EAAE,CAAC;oBAC1E,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;wBAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;wBAC9D,sBAAO;qBACR;;;;oBAIU,qBAAM,IAAI,eAAM,EAAE,CAAC,UAAU,CACpC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAC/D,IAAI,CAAC,KAAK,CACX,EAAA;;oBAHD,MAAM,GAAG,SAGR,CAAC;;;;oBAEF,wFAAwF;oBACxF,
|
|
1
|
+
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../../src/routes/signup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAC3C,kDAAsD;AACtD,wCAAqD;AACrD,uEAAsE;AACtE,6CAA4C;AAE5C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACU,QAAA,MAAM,GAAU;IAC3B,IAAI,EAAE,aAAM,CAAC,MAAM,CAAC,IAAI;IACxB,MAAM,EAAE,aAAM,CAAC,MAAM,CAAC,MAAM;IAC5B,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,IAAI,GAA6C,MAAA,OAAO,CAAC,IAAI,mCAAI,EAAE,CAAC;oBAC1E,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;wBAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;wBAC9D,sBAAO;qBACR;;;;oBAIU,qBAAM,IAAI,eAAM,EAAE,CAAC,UAAU,CACpC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAC/D,IAAI,CAAC,KAAK,CACX,EAAA;;oBAHD,MAAM,GAAG,SAGR,CAAC;;;;oBAEF,wFAAwF;oBACxF,4FAA4F;oBAC5F,6FAA6F;oBAC7F,iDAAiD;oBACjD,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,0BAAc,EAAE,CAAC,WAAW,CAAC,OAAK,CAAC,EAAE,CAAC,CAAC;oBAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAK,YAAY,KAAK,CAAC,CAAC,CAAC,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;oBACrF,sBAAO;;yBAGL,CAAA,MAAM,CAAC,OAAO,KAAK,SAAS,CAAA,EAA5B,wBAA4B;oBAC9B,qBAAM,IAAA,mCAAgB,EAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAA;;oBAA7C,SAA6C,CAAC;;;oBAGhD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;;;SACnB;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateResetPasswordToken.d.ts","sourceRoot":"","sources":["../../../src/routes/validateResetPasswordToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"validateResetPasswordToken.d.ts","sourceRoot":"","sources":["../../../src/routes/validateResetPasswordToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAM9C,eAAO,MAAM,0BAA0B,EAAE,KAqCxC,CAAC"}
|
|
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
exports.validateResetPasswordToken = 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 PasswordResetToken_1 = require("../authentication/PasswordResetToken");
|
|
43
44
|
exports.validateResetPasswordToken = {
|
|
44
45
|
path: user_1.routes.validateResetToken.path,
|
|
@@ -67,7 +68,10 @@ exports.validateResetPasswordToken = {
|
|
|
67
68
|
return [2 /*return*/];
|
|
68
69
|
}
|
|
69
70
|
if (resolution.status === 'expired') {
|
|
70
|
-
logger.info({
|
|
71
|
+
logger.info({
|
|
72
|
+
message: "Expired reset token used",
|
|
73
|
+
obj: { account: new util_node_1.RequestDigests().account(resolution.user.email) },
|
|
74
|
+
});
|
|
71
75
|
response.status(200).send({ isValid: false, message: 'Token has expired' });
|
|
72
76
|
return [2 /*return*/];
|
|
73
77
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateResetPasswordToken.js","sourceRoot":"","sources":["../../../src/routes/validateResetPasswordToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAyC;AACzC,4CAA2C;AAC3C,2EAA0E;AAE7D,QAAA,0BAA0B,GAAU;IAC/C,IAAI,EAAE,aAAM,CAAC,kBAAkB,CAAC,IAAI;IACpC,MAAM,EAAE,aAAM,CAAC,kBAAkB,CAAC,MAAM;IACxC,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;;;;oBAC3B,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;oBAClD,KAAK,GAAK,OAAO,CAAC,KAAK,MAAlB,CAAmB;oBAChC,IAAI,CAAC,KAAK,EAAE;wBACV,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;wBAC5E,sBAAO;qBACR;oBAEK,UAAU,GAAG,IAAI,uCAAkB,EAAE,CAAC;oBACzB,qBAAM,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAA;;oBAA5C,UAAU,GAAG,SAA+B;oBAClD,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE;wBACxE,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,0BAA0B;4BACnC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;yBACzE,CAAC,CAAC;wBACH,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;wBACxE,sBAAO;qBACR;oBAED,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE;wBACnC,MAAM,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"validateResetPasswordToken.js","sourceRoot":"","sources":["../../../src/routes/validateResetPasswordToken.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wCAAyC;AACzC,4CAA2C;AAC3C,kDAAsD;AACtD,2EAA0E;AAE7D,QAAA,0BAA0B,GAAU;IAC/C,IAAI,EAAE,aAAM,CAAC,kBAAkB,CAAC,IAAI;IACpC,MAAM,EAAE,aAAM,CAAC,kBAAkB,CAAC,MAAM;IACxC,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;;;;oBAC3B,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC;oBAClD,KAAK,GAAK,OAAO,CAAC,KAAK,MAAlB,CAAmB;oBAChC,IAAI,CAAC,KAAK,EAAE;wBACV,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;wBAC5E,sBAAO;qBACR;oBAEK,UAAU,GAAG,IAAI,uCAAkB,EAAE,CAAC;oBACzB,qBAAM,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAA;;oBAA5C,UAAU,GAAG,SAA+B;oBAClD,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE;wBACxE,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,0BAA0B;4BACnC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE;yBACzE,CAAC,CAAC;wBACH,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;wBACxE,sBAAO;qBACR;oBAED,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE;wBACnC,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,0BAA0B;4BACnC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,0BAAc,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;yBACtE,CAAC,CAAC;wBACH,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;wBAC5E,sBAAO;qBACR;oBAED,oFAAoF;oBACpF,uFAAuF;oBACvF,wFAAwF;oBACxF,mFAAmF;oBACnF,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;;;;SAC5E;CACF,CAAC"}
|
|
@@ -11,11 +11,20 @@ import { Service } from '@proteinjs/service';
|
|
|
11
11
|
* account's existing sessions (the old
|
|
12
12
|
* credential dies with them), and returns the plaintext ONCE for pasting into the declaration's
|
|
13
13
|
* Secret Manager secret. The same call rotates. Machine rows only (`is_loaded_from_source`);
|
|
14
|
-
* human credentials go through the password-reset flow.
|
|
14
|
+
* human credentials go through the password-reset flow. A declared address held by a row the
|
|
15
|
+
* boot sync does not own (a person's signup, a hand-made row) has no machine account at all —
|
|
16
|
+
* the sync refused the declaration — and both the list and the mint say so.
|
|
15
17
|
*/
|
|
16
18
|
export declare class MachineCredentials implements MachineCredentialsService {
|
|
17
19
|
serviceMetadata: Service['serviceMetadata'];
|
|
18
20
|
listMachineAccounts(): Promise<MachineAccountView[]>;
|
|
19
21
|
mintCredential(email: string): Promise<MintedMachineCredential>;
|
|
22
|
+
/**
|
|
23
|
+
* Why the boot sync refused a declaration whose address this row holds — undefined for the
|
|
24
|
+
* account's own row. The sync owns a row only when it created it (`isLoadedFromSource`); any
|
|
25
|
+
* other row under a declared address is never taken over (@proteinjs/db's natural-key refusal),
|
|
26
|
+
* and the one machine marker says whose row it is.
|
|
27
|
+
*/
|
|
28
|
+
private refusal;
|
|
20
29
|
}
|
|
21
30
|
//# sourceMappingURL=MachineCredentials.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MachineCredentials.d.ts","sourceRoot":"","sources":["../../../src/services/MachineCredentials.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"MachineCredentials.d.ts","sourceRoot":"","sources":["../../../src/services/MachineCredentials.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EAKxB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,YAAW,yBAAyB;IAC3D,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAIhD;IAEI,mBAAmB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA0BpD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAkDrE;;;;;OAKG;IACH,OAAO,CAAC,OAAO;CAOhB"}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
14
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
15
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -50,6 +61,7 @@ var crypto_1 = require("crypto");
|
|
|
50
61
|
var db_1 = require("@proteinjs/db");
|
|
51
62
|
var user_1 = require("@proteinjs/user");
|
|
52
63
|
var logger_1 = require("@proteinjs/logger");
|
|
64
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
53
65
|
var PasswordHasher_1 = require("../authentication/PasswordHasher");
|
|
54
66
|
/**
|
|
55
67
|
* Credential minting for code-declared machine accounts — the ONLY manual step in a machine
|
|
@@ -62,7 +74,9 @@ var PasswordHasher_1 = require("../authentication/PasswordHasher");
|
|
|
62
74
|
* account's existing sessions (the old
|
|
63
75
|
* credential dies with them), and returns the plaintext ONCE for pasting into the declaration's
|
|
64
76
|
* Secret Manager secret. The same call rotates. Machine rows only (`is_loaded_from_source`);
|
|
65
|
-
* human credentials go through the password-reset flow.
|
|
77
|
+
* human credentials go through the password-reset flow. A declared address held by a row the
|
|
78
|
+
* boot sync does not own (a person's signup, a hand-made row) has no machine account at all —
|
|
79
|
+
* the sync refused the declaration — and both the list and the mint say so.
|
|
66
80
|
*/
|
|
67
81
|
var MachineCredentials = /** @class */ (function () {
|
|
68
82
|
function MachineCredentials() {
|
|
@@ -74,7 +88,7 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
74
88
|
}
|
|
75
89
|
MachineCredentials.prototype.listMachineAccounts = function () {
|
|
76
90
|
return __awaiter(this, void 0, void 0, function () {
|
|
77
|
-
var db, views, _i, _a, declaration, row,
|
|
91
|
+
var db, views, _i, _a, declaration, row, refusal;
|
|
78
92
|
return __generator(this, function (_b) {
|
|
79
93
|
switch (_b.label) {
|
|
80
94
|
case 0:
|
|
@@ -88,15 +102,14 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
88
102
|
return [4 /*yield*/, db.get(user_1.tables.User, { email: declaration.email })];
|
|
89
103
|
case 2:
|
|
90
104
|
row = _b.sent();
|
|
91
|
-
|
|
92
|
-
views.push({
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
105
|
+
refusal = row && this.refusal(row);
|
|
106
|
+
views.push(__assign(__assign({ email: declaration.email, accountName: declaration.accountName, roles: __spreadArray([], declaration.roles, true), secretName: declaration.secretName, status: !row
|
|
107
|
+
? 'pending first boot'
|
|
108
|
+
: refusal
|
|
109
|
+
? 'declaration refused'
|
|
110
|
+
: row.status === 'deactivated'
|
|
111
|
+
? 'deactivated'
|
|
112
|
+
: 'active' }, (refusal ? { refusal: refusal } : {})), { hasCredential: !!row && !refusal && !!row.password }));
|
|
100
113
|
_b.label = 3;
|
|
101
114
|
case 3:
|
|
102
115
|
_i++;
|
|
@@ -108,7 +121,7 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
108
121
|
};
|
|
109
122
|
MachineCredentials.prototype.mintCredential = function (email) {
|
|
110
123
|
return __awaiter(this, void 0, void 0, function () {
|
|
111
|
-
var logger, normalizedEmail, declaration, db, user, password, _a, _b, _c;
|
|
124
|
+
var logger, normalizedEmail, declaration, db, user, refusal, password, _a, _b, _c;
|
|
112
125
|
var _d;
|
|
113
126
|
return __generator(this, function (_e) {
|
|
114
127
|
switch (_e.label) {
|
|
@@ -124,9 +137,15 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
124
137
|
return [4 /*yield*/, db.get(user_1.tables.User, { email: normalizedEmail })];
|
|
125
138
|
case 1:
|
|
126
139
|
user = _e.sent();
|
|
127
|
-
if (!user
|
|
140
|
+
if (!user) {
|
|
128
141
|
throw new Error("The machine account row for '".concat(normalizedEmail, "' has not been loaded from source yet \u2014 ") +
|
|
129
|
-
"the boot sync creates
|
|
142
|
+
"the boot sync creates it. Boot the server with the declaration, then mint.");
|
|
143
|
+
}
|
|
144
|
+
refusal = this.refusal(user);
|
|
145
|
+
if (refusal) {
|
|
146
|
+
throw new Error("The declaration for '".concat(normalizedEmail, "' was refused at boot: ").concat(refusal, " \u2014 the boot sync ") +
|
|
147
|
+
"never takes over a row it does not own, so there is no machine account to mint for. The " +
|
|
148
|
+
"first boot after that row is gone creates it.");
|
|
130
149
|
}
|
|
131
150
|
password = (0, crypto_1.randomBytes)(32).toString('hex');
|
|
132
151
|
_b = (_a = db).update;
|
|
@@ -145,7 +164,7 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
145
164
|
_e.sent();
|
|
146
165
|
logger.info({
|
|
147
166
|
message: "Minted machine credential",
|
|
148
|
-
obj: {
|
|
167
|
+
obj: { account: new util_node_1.RequestDigests().account(normalizedEmail), secretName: declaration.secretName },
|
|
149
168
|
});
|
|
150
169
|
return [2 /*return*/, {
|
|
151
170
|
email: normalizedEmail,
|
|
@@ -158,6 +177,18 @@ var MachineCredentials = /** @class */ (function () {
|
|
|
158
177
|
});
|
|
159
178
|
});
|
|
160
179
|
};
|
|
180
|
+
/**
|
|
181
|
+
* Why the boot sync refused a declaration whose address this row holds — undefined for the
|
|
182
|
+
* account's own row. The sync owns a row only when it created it (`isLoadedFromSource`); any
|
|
183
|
+
* other row under a declared address is never taken over (@proteinjs/db's natural-key refusal),
|
|
184
|
+
* and the one machine marker says whose row it is.
|
|
185
|
+
*/
|
|
186
|
+
MachineCredentials.prototype.refusal = function (row) {
|
|
187
|
+
if (row.isLoadedFromSource === true) {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
return row.machine === true ? 'a hand-made machine row holds this address' : 'a person holds this address';
|
|
191
|
+
};
|
|
161
192
|
return MachineCredentials;
|
|
162
193
|
}());
|
|
163
194
|
exports.MachineCredentials = MachineCredentials;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MachineCredentials.js","sourceRoot":"","sources":["../../../src/services/MachineCredentials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MachineCredentials.js","sourceRoot":"","sources":["../../../src/services/MachineCredentials.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iCAAqC;AACrC,oCAA8C;AAC9C,wCASyB;AACzB,4CAA2C;AAC3C,kDAAsD;AAEtD,mEAAkE;AAElE;;;;;;;;;;;;;;GAcG;AACH;IAAA;QACS,oBAAe,GAA+B;YACnD,IAAI,EAAE;gBACJ,UAAU,EAAE,uBAAgB,CAAC,KAAK;aACnC;SACF,CAAC;IA2FJ,CAAC;IAzFO,gDAAmB,GAAzB;;;;;;wBACQ,EAAE,GAAG,IAAA,kBAAa,GAAE,CAAC;wBACrB,KAAK,GAAyB,EAAE,CAAC;8BACO,EAApB,SAAA,yBAAkB,GAAE;;;6BAApB,CAAA,cAAoB,CAAA;wBAAnC,WAAW;wBACU,qBAAM,EAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,EAAA;;wBAA/E,GAAG,GAAqB,SAAuD;wBAC/E,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;wBACzC,KAAK,CAAC,IAAI,qBACR,KAAK,EAAE,WAAW,CAAC,KAAK,EACxB,WAAW,EAAE,WAAW,CAAC,WAAW,EACpC,KAAK,oBAAM,WAAW,CAAC,KAAK,SAC5B,UAAU,EAAE,WAAW,CAAC,UAAU,EAClC,MAAM,EAAE,CAAC,GAAG;gCACV,CAAC,CAAC,oBAAoB;gCACtB,CAAC,CAAC,OAAO;oCACP,CAAC,CAAC,qBAAqB;oCACvB,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,aAAa;wCAC5B,CAAC,CAAC,aAAa;wCACf,CAAC,CAAC,QAAQ,IACb,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,SAAA,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC/B,aAAa,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,IAClD,CAAC;;;wBAjBqB,IAAoB,CAAA;;4BAoB9C,sBAAO,KAAK,EAAC;;;;KACd;IAEK,2CAAc,GAApB,UAAqB,KAAa;;;;;;;wBAC1B,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,mCAAmC,EAAE,CAAC,CAAC;wBACnE,eAAe,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,WAAW,EAAE,CAAC;wBACvC,WAAW,GAAG,IAAA,yBAAkB,GAAE,CAAC,IAAI,CAAC,UAAC,cAAc,IAAK,OAAA,cAAc,CAAC,KAAK,KAAK,eAAe,EAAxC,CAAwC,CAAC,CAAC;wBAC5G,IAAI,CAAC,WAAW,EAAE;4BAChB,MAAM,IAAI,KAAK,CACb,8CAAuC,KAAK,2CAAwC;gCAClF,+DAA+D,CAClE,CAAC;yBACH;wBAEK,EAAE,GAAG,IAAA,kBAAa,GAAE,CAAC;wBACI,qBAAM,EAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,EAAA;;wBAA9E,IAAI,GAAqB,SAAqD;wBACpF,IAAI,CAAC,IAAI,EAAE;4BACT,MAAM,IAAI,KAAK,CACb,uCAAgC,eAAe,kDAA0C;gCACvF,4EAA4E,CAC/E,CAAC;yBACH;wBAEK,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;wBACnC,IAAI,OAAO,EAAE;4BACX,MAAM,IAAI,KAAK,CACb,+BAAwB,eAAe,oCAA0B,OAAO,2BAAmB;gCACzF,0FAA0F;gCAC1F,+CAA+C,CAClD,CAAC;yBACH;wBAGK,QAAQ,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;wBAC3C,KAAA,CAAA,KAAA,EAAE,CAAA,CAAC,MAAM,CAAA;8BAAC,aAAM,CAAC,IAAI;+BAAI,EAAE,EAAE,IAAI,CAAC,EAAE;wBAAY,qBAAM,IAAI,+BAAc,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAA;4BAA1G,qBAAM,yBAAsC,WAAQ,GAAE,SAAoD,QAAG,EAAA;;wBAA7G,SAA6G,CAAC;wBAC9G,yFAAyF;wBACzF,yEAAyE;wBACzE,qBAAM,EAAE,CAAC,MAAM,CAAC,aAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,EAAA;;wBAF/D,yFAAyF;wBACzF,yEAAyE;wBACzE,SAA+D,CAAC;wBAChE,MAAM,CAAC,IAAI,CAAC;4BACV,OAAO,EAAE,2BAA2B;4BACpC,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,0BAAc,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,UAAU,EAAE;yBACpG,CAAC,CAAC;wBAEH,sBAAO;gCACL,KAAK,EAAE,eAAe;gCACtB,QAAQ,UAAA;gCACR,UAAU,EAAE,WAAW,CAAC,UAAU;gCAClC,IAAI,EACF,oDAA6C,WAAW,CAAC,UAAU,sBAAmB;oCACtF,mGAA8F;6BACjG,EAAC;;;;KACH;IAED;;;;;OAKG;IACK,oCAAO,GAAf,UAAgB,GAAS;QACvB,IAAI,GAAG,CAAC,kBAAkB,KAAK,IAAI,EAAE;YACnC,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,6BAA6B,CAAC;IAC7G,CAAC;IACH,yBAAC;AAAD,CAAC,AAhGD,IAgGC;AAhGY,gDAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA8D,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA8D,MAAM,iBAAiB,CAAC;AAG3G,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,iHAAiH;AACjH,MAAM,MAAM,qBAAqB,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC;AAEpH,qBAAa,KAAM,YAAW,YAAY;IACjC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAIhD;IAEI,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,cAAc,GAAG,YAAY,CAAC;IAwBvF;;;;;;;;;;;;;;;;OAgBG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;YAuCtE,UAAU;IA8ExB,+GAA+G;YACjG,WAAW;CAK1B"}
|
|
@@ -49,6 +49,7 @@ exports.Roles = void 0;
|
|
|
49
49
|
var db_1 = require("@proteinjs/db");
|
|
50
50
|
var user_1 = require("@proteinjs/user");
|
|
51
51
|
var logger_1 = require("@proteinjs/logger");
|
|
52
|
+
var util_node_1 = require("@proteinjs/util-node");
|
|
52
53
|
var Roles = /** @class */ (function () {
|
|
53
54
|
function Roles() {
|
|
54
55
|
this.serviceMetadata = {
|
|
@@ -132,7 +133,10 @@ var Roles = /** @class */ (function () {
|
|
|
132
133
|
}); })];
|
|
133
134
|
case 3:
|
|
134
135
|
_b.sent();
|
|
135
|
-
logger.info({
|
|
136
|
+
logger.info({
|
|
137
|
+
message: 'Break-glass admin granted by the dev first-admin door',
|
|
138
|
+
obj: { target: user.id, account: new util_node_1.RequestDigests().account(email) },
|
|
139
|
+
});
|
|
136
140
|
return [2 /*return*/, 'granted'];
|
|
137
141
|
}
|
|
138
142
|
});
|
|
@@ -219,7 +223,7 @@ var Roles = /** @class */ (function () {
|
|
|
219
223
|
_c.sent();
|
|
220
224
|
logger.info({
|
|
221
225
|
message: 'Roles granted by the dev role-bootstrap door',
|
|
222
|
-
obj: { target: user.id,
|
|
226
|
+
obj: { target: user.id, account: new util_node_1.RequestDigests().account(email), granted: outcome.granted },
|
|
223
227
|
});
|
|
224
228
|
return [2 /*return*/, outcome];
|
|
225
229
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAAmE;AACnE,wCAA2G;AAC3G,4CAA2C;
|
|
1
|
+
{"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"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"}
|
|
@@ -71,6 +71,11 @@ export declare class Signup implements SignupService {
|
|
|
71
71
|
* (`devLogin`, which auto-creates missing same-domain test accounts). Not exposed as an RPC:
|
|
72
72
|
* the service surface is the `SignupService` INTERFACE (ServiceRouter walks its declared
|
|
73
73
|
* methods), so extra class methods stay server-internal.
|
|
74
|
+
*
|
|
75
|
+
* An address a `MachineAccount` declaration owns is never registered, whatever its row state:
|
|
76
|
+
* a person's row under it would make the boot sync refuse the declaration (it never takes over
|
|
77
|
+
* a row it does not own), so the address is refused here in plain words — the declared machine
|
|
78
|
+
* accounts of this build are the list, nothing else.
|
|
74
79
|
*/
|
|
75
80
|
createAccount(account: {
|
|
76
81
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Signup.d.ts","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAIlB,aAAa,EACb,wBAAwB,EAExB,MAAM,EACN,IAAI,EACJ,UAAU,
|
|
1
|
+
{"version":3,"file":"Signup.d.ts","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAIlB,aAAa,EACb,wBAAwB,EAExB,MAAM,EACN,IAAI,EACJ,UAAU,EAGX,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EAAE,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAGnE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAEhH,MAAM,WAAW,0BAA2B,SAAQ,QAAQ;IAC1D,SAAS,IAAI,YAAY,CAAC;CAC3B;AAED,eAAO,MAAM,6BAA6B,QAAO,0BAShD,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,MAAO,YAAW,aAAa;IACnC,eAAe;;oCAEM,MAAM,QAAQ,GAAG,EAAE;;MAY7C;IAEF;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA8DvE,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgD5D;;;;;;OAMG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiCxD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWhD;;;OAGG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAoD1F;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,OAAO,EAAE;QAC3B,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,OAAO,CAAC;QACvB,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;KAC9B,GAAG,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC;IAuBjC,iGAAiG;YACnF,YAAY;IAe1B,8GAA8G;IAC9G,OAAO,CAAC,iBAAiB;IAUzB,8GAA8G;IAC9G,OAAO,CAAC,eAAe;IAOvB,qGAAqG;YACvF,WAAW;CAU1B"}
|