@proteinjs/user-server 1.21.1 → 1.22.1
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 +22 -0
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +5 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/authentication/PasswordResetToken.d.ts +43 -12
- package/dist/src/authentication/PasswordResetToken.d.ts.map +1 -1
- package/dist/src/authentication/PasswordResetToken.js +86 -21
- package/dist/src/authentication/PasswordResetToken.js.map +1 -1
- package/dist/src/routes/devLogin.d.ts +1 -1
- package/dist/src/routes/devLogin.js +1 -1
- package/dist/src/routes/devMail.d.ts +4 -0
- package/dist/src/routes/devMail.d.ts.map +1 -0
- package/dist/src/routes/devMail.js +119 -0
- package/dist/src/routes/devMail.js.map +1 -0
- package/dist/src/routes/executePasswordReset.d.ts +2 -1
- package/dist/src/routes/executePasswordReset.d.ts.map +1 -1
- package/dist/src/routes/executePasswordReset.js +9 -7
- package/dist/src/routes/executePasswordReset.js.map +1 -1
- package/dist/src/routes/initiatePasswordReset.d.ts +3 -2
- package/dist/src/routes/initiatePasswordReset.d.ts.map +1 -1
- package/dist/src/routes/initiatePasswordReset.js +30 -27
- package/dist/src/routes/initiatePasswordReset.js.map +1 -1
- package/dist/test/DbTraffic.d.ts +29 -0
- package/dist/test/DbTraffic.d.ts.map +1 -0
- package/dist/test/DbTraffic.js +106 -0
- package/dist/test/DbTraffic.js.map +1 -0
- package/dist/test/DevLoginBootstrapAdmin.test.js +3 -4
- package/dist/test/DevLoginBootstrapAdmin.test.js.map +1 -1
- package/dist/test/DevLoginStaleCookieFirstHit.test.js +1 -1
- package/dist/test/DevLoginStaleCookieFirstHit.test.js.map +1 -1
- package/dist/test/DevMail.test.d.ts +2 -0
- package/dist/test/DevMail.test.d.ts.map +1 -0
- package/dist/test/DevMail.test.js +250 -0
- package/dist/test/DevMail.test.js.map +1 -0
- package/dist/test/ExecutePasswordReset.test.js +513 -124
- package/dist/test/ExecutePasswordReset.test.js.map +1 -1
- package/dist/test/InitiatePasswordReset.test.d.ts +2 -0
- package/dist/test/InitiatePasswordReset.test.d.ts.map +1 -0
- package/dist/test/InitiatePasswordReset.test.js +415 -0
- package/dist/test/InitiatePasswordReset.test.js.map +1 -0
- package/dist/test/LogCapture.d.ts +22 -0
- package/dist/test/LogCapture.d.ts.map +1 -0
- package/dist/test/LogCapture.js +127 -0
- package/dist/test/LogCapture.js.map +1 -0
- package/dist/test/MalformedResetTokens.d.ts +11 -0
- package/dist/test/MalformedResetTokens.d.ts.map +1 -0
- package/dist/test/MalformedResetTokens.js +35 -0
- package/dist/test/MalformedResetTokens.js.map +1 -0
- package/dist/test/ValidateResetToken.test.js +156 -33
- package/dist/test/ValidateResetToken.test.js.map +1 -1
- package/dist/test/emulatorLock.test.d.ts +2 -0
- package/dist/test/emulatorLock.test.d.ts.map +1 -0
- package/dist/test/emulatorLock.test.js +32 -0
- package/dist/test/emulatorLock.test.js.map +1 -0
- package/dist/test/emulatorLockName.test.d.ts +2 -0
- package/dist/test/emulatorLockName.test.d.ts.map +1 -0
- package/dist/test/emulatorLockName.test.js +36 -0
- package/dist/test/emulatorLockName.test.js.map +1 -0
- package/generated/index.ts +5 -1
- package/index.ts +1 -1
- package/jest.config.js +2 -2
- package/package.json +4 -4
- package/src/authentication/PasswordResetToken.ts +74 -20
- package/src/routes/devLogin.ts +1 -1
- package/src/routes/devMail.ts +72 -0
- package/src/routes/executePasswordReset.ts +3 -2
- package/src/routes/initiatePasswordReset.ts +20 -17
- package/test/DbTraffic.ts +43 -0
- package/test/DevLoginBootstrapAdmin.test.ts +3 -4
- package/test/DevLoginStaleCookieFirstHit.test.ts +1 -1
- package/test/DevMail.test.ts +151 -0
- package/test/ExecutePasswordReset.test.ts +308 -70
- package/test/InitiatePasswordReset.test.ts +250 -0
- package/test/LogCapture.ts +54 -0
- package/test/MalformedResetTokens.ts +27 -0
- package/test/ValidateResetToken.test.ts +108 -24
- package/test/emulatorLock.js +5 -6
- package/test/emulatorLock.test.ts +32 -0
- package/test/emulatorLockName.test.ts +33 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var email_server_1 = require("@proteinjs/email-server");
|
|
40
|
+
var devMail_1 = require("../src/routes/devMail");
|
|
41
|
+
/**
|
|
42
|
+
* `GET /dev/mail` and `GET /dev/mail/<id>` — the dev-only door onto the mail sink, gated exactly
|
|
43
|
+
* like `/dev/login`: `DEVELOPMENT` AND `DEV_AUTO_LOGIN_EMAIL`, else 404 as if unregistered. With
|
|
44
|
+
* the gates open, the last invite a development sender recorded is readable — its link off the
|
|
45
|
+
* list, its rendered html off the message — so a lane never needs a real inbox. No database:
|
|
46
|
+
* the sink is the process's own ring.
|
|
47
|
+
*/
|
|
48
|
+
var ENV_EMAIL = 'dev@test.local';
|
|
49
|
+
var invoke = function (route, _a) {
|
|
50
|
+
var _b = _a === void 0 ? {} : _a, query = _b.query, params = _b.params;
|
|
51
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
|
52
|
+
var outcome, response;
|
|
53
|
+
return __generator(this, function (_c) {
|
|
54
|
+
switch (_c.label) {
|
|
55
|
+
case 0:
|
|
56
|
+
outcome = {};
|
|
57
|
+
response = {
|
|
58
|
+
status: function (code) {
|
|
59
|
+
outcome.status = code;
|
|
60
|
+
return this;
|
|
61
|
+
},
|
|
62
|
+
type: function (kind) {
|
|
63
|
+
outcome.type = kind;
|
|
64
|
+
return this;
|
|
65
|
+
},
|
|
66
|
+
send: function (body) {
|
|
67
|
+
outcome.body = body;
|
|
68
|
+
},
|
|
69
|
+
json: function (body) {
|
|
70
|
+
outcome.body = body;
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
return [4 /*yield*/, route.onRequest({ query: query !== null && query !== void 0 ? query : {}, params: params !== null && params !== void 0 ? params : {} }, response)];
|
|
74
|
+
case 1:
|
|
75
|
+
_c.sent();
|
|
76
|
+
return [2 /*return*/, outcome];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
var INVITE_LINK = 'http://localhost:7985/auth/signup?token=abc123';
|
|
82
|
+
var INVITE_HTML = "<html><body><p>You are invited.</p><a href=\"".concat(INVITE_LINK, "\">Accept</a></body></html>");
|
|
83
|
+
/** The product's path onto the sink: a development sender with a real-looking SMTP config, no opt-in. */
|
|
84
|
+
var sendInviteThroughSender = function (to) { return __awaiter(void 0, void 0, void 0, function () {
|
|
85
|
+
return __generator(this, function (_a) {
|
|
86
|
+
switch (_a.label) {
|
|
87
|
+
case 0: return [4 /*yield*/, new email_server_1.EmailSender({
|
|
88
|
+
host: 'smtp.test.local',
|
|
89
|
+
port: 465,
|
|
90
|
+
secure: true,
|
|
91
|
+
auth: { user: 'mailbox@test.local', pass: 'unused' },
|
|
92
|
+
from: '"Example" <hi@example.com>',
|
|
93
|
+
}).sendEmail({ to: to, subject: "You're invited", text: "Accept your invite: ".concat(INVITE_LINK), html: INVITE_HTML })];
|
|
94
|
+
case 1:
|
|
95
|
+
_a.sent();
|
|
96
|
+
return [2 /*return*/];
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}); };
|
|
100
|
+
describe('devMail routes', function () {
|
|
101
|
+
var originalEnv = {
|
|
102
|
+
DEVELOPMENT: process.env.DEVELOPMENT,
|
|
103
|
+
DEV_AUTO_LOGIN_EMAIL: process.env.DEV_AUTO_LOGIN_EMAIL,
|
|
104
|
+
EMAIL_TRANSPORT: process.env.EMAIL_TRANSPORT,
|
|
105
|
+
EMAIL_ALLOW_REAL_SEND: process.env.EMAIL_ALLOW_REAL_SEND,
|
|
106
|
+
};
|
|
107
|
+
beforeEach(function () {
|
|
108
|
+
process.env.DEVELOPMENT = 'true';
|
|
109
|
+
process.env.DEV_AUTO_LOGIN_EMAIL = ENV_EMAIL;
|
|
110
|
+
delete process.env.EMAIL_TRANSPORT;
|
|
111
|
+
delete process.env.EMAIL_ALLOW_REAL_SEND;
|
|
112
|
+
email_server_1.MailSink.get().clear();
|
|
113
|
+
});
|
|
114
|
+
afterEach(function () {
|
|
115
|
+
for (var _i = 0, _a = Object.entries(originalEnv); _i < _a.length; _i++) {
|
|
116
|
+
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
117
|
+
if (value === undefined) {
|
|
118
|
+
delete process.env[key];
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
process.env[key] = value;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it("lists the last sent messages newest first — the invite's recipient, subject, first link and timestamp — and the message renders its html", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
126
|
+
var list, messages, message;
|
|
127
|
+
return __generator(this, function (_a) {
|
|
128
|
+
switch (_a.label) {
|
|
129
|
+
case 0: return [4 /*yield*/, sendInviteThroughSender('earlier@test.local')];
|
|
130
|
+
case 1:
|
|
131
|
+
_a.sent();
|
|
132
|
+
return [4 /*yield*/, sendInviteThroughSender('lane-after@test.local')];
|
|
133
|
+
case 2:
|
|
134
|
+
_a.sent();
|
|
135
|
+
return [4 /*yield*/, invoke(devMail_1.devMail)];
|
|
136
|
+
case 3:
|
|
137
|
+
list = _a.sent();
|
|
138
|
+
expect(list.status).toBe(200);
|
|
139
|
+
messages = list.body.messages;
|
|
140
|
+
expect(messages).toHaveLength(2);
|
|
141
|
+
expect(messages[0]).toMatchObject({
|
|
142
|
+
to: ['lane-after@test.local'],
|
|
143
|
+
subject: "You're invited",
|
|
144
|
+
link: INVITE_LINK,
|
|
145
|
+
from: 'hi@example.com',
|
|
146
|
+
refused: true,
|
|
147
|
+
});
|
|
148
|
+
expect(typeof messages[0].id).toBe('string');
|
|
149
|
+
expect(Date.parse(String(messages[0].at))).not.toBeNaN();
|
|
150
|
+
expect(messages[0].url).toBe("/dev/mail/".concat(messages[0].id));
|
|
151
|
+
expect(messages[1].to).toEqual(['earlier@test.local']);
|
|
152
|
+
return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: String(messages[0].id) } })];
|
|
153
|
+
case 4:
|
|
154
|
+
message = _a.sent();
|
|
155
|
+
expect(message.status).toBe(200);
|
|
156
|
+
expect(message.type).toBe('html');
|
|
157
|
+
expect(message.body).toBe(INVITE_HTML);
|
|
158
|
+
return [2 /*return*/];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}); });
|
|
162
|
+
it('?n= bounds the list; a text-only message renders as text; an unknown id is 404', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
163
|
+
var one, all, messages, plain, _a;
|
|
164
|
+
return __generator(this, function (_b) {
|
|
165
|
+
switch (_b.label) {
|
|
166
|
+
case 0:
|
|
167
|
+
process.env.EMAIL_TRANSPORT = 'sink';
|
|
168
|
+
return [4 /*yield*/, new email_server_1.EmailSender({ host: 'h', port: 465, secure: true, from: '"Example" <hi@example.com>' }).sendEmail({
|
|
169
|
+
to: 'a@test.local',
|
|
170
|
+
subject: 'Plain',
|
|
171
|
+
text: 'just text',
|
|
172
|
+
})];
|
|
173
|
+
case 1:
|
|
174
|
+
_b.sent();
|
|
175
|
+
return [4 /*yield*/, sendInviteThroughSender('b@test.local')];
|
|
176
|
+
case 2:
|
|
177
|
+
_b.sent();
|
|
178
|
+
return [4 /*yield*/, invoke(devMail_1.devMail, { query: { n: '1' } })];
|
|
179
|
+
case 3:
|
|
180
|
+
one = _b.sent();
|
|
181
|
+
expect(one.body.messages).toHaveLength(1);
|
|
182
|
+
return [4 /*yield*/, invoke(devMail_1.devMail, { query: { n: 'garbage' } })];
|
|
183
|
+
case 4:
|
|
184
|
+
all = _b.sent();
|
|
185
|
+
messages = all.body.messages;
|
|
186
|
+
expect(messages.map(function (m) { return m.subject; })).toEqual(["You're invited", 'Plain']);
|
|
187
|
+
expect(messages[1].refused).toBe(false);
|
|
188
|
+
return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: messages[1].id } })];
|
|
189
|
+
case 5:
|
|
190
|
+
plain = _b.sent();
|
|
191
|
+
expect(plain.status).toBe(200);
|
|
192
|
+
expect(plain.type).toBe('text');
|
|
193
|
+
expect(plain.body).toBe('just text');
|
|
194
|
+
_a = expect;
|
|
195
|
+
return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: 'nope' } })];
|
|
196
|
+
case 6:
|
|
197
|
+
_a.apply(void 0, [(_b.sent()).status]).toBe(404);
|
|
198
|
+
return [2 /*return*/];
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}); });
|
|
202
|
+
it('DEVELOPMENT unset → 404 on both paths, even with messages in the sink', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
203
|
+
var record, _a, _b;
|
|
204
|
+
return __generator(this, function (_c) {
|
|
205
|
+
switch (_c.label) {
|
|
206
|
+
case 0: return [4 /*yield*/, sendInviteThroughSender('lane@test.local')];
|
|
207
|
+
case 1:
|
|
208
|
+
_c.sent();
|
|
209
|
+
record = email_server_1.MailSink.get().list()[0];
|
|
210
|
+
delete process.env.DEVELOPMENT;
|
|
211
|
+
_a = expect;
|
|
212
|
+
return [4 /*yield*/, invoke(devMail_1.devMail)];
|
|
213
|
+
case 2:
|
|
214
|
+
_a.apply(void 0, [(_c.sent()).status]).toBe(404);
|
|
215
|
+
_b = expect;
|
|
216
|
+
return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: record.id } })];
|
|
217
|
+
case 3:
|
|
218
|
+
_b.apply(void 0, [(_c.sent()).status]).toBe(404);
|
|
219
|
+
return [2 /*return*/];
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}); });
|
|
223
|
+
it('DEV_AUTO_LOGIN_EMAIL unset (or blank) → 404 on both paths', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
224
|
+
var record, _a, _b, _c;
|
|
225
|
+
return __generator(this, function (_d) {
|
|
226
|
+
switch (_d.label) {
|
|
227
|
+
case 0: return [4 /*yield*/, sendInviteThroughSender('lane@test.local')];
|
|
228
|
+
case 1:
|
|
229
|
+
_d.sent();
|
|
230
|
+
record = email_server_1.MailSink.get().list()[0];
|
|
231
|
+
delete process.env.DEV_AUTO_LOGIN_EMAIL;
|
|
232
|
+
_a = expect;
|
|
233
|
+
return [4 /*yield*/, invoke(devMail_1.devMail)];
|
|
234
|
+
case 2:
|
|
235
|
+
_a.apply(void 0, [(_d.sent()).status]).toBe(404);
|
|
236
|
+
_b = expect;
|
|
237
|
+
return [4 /*yield*/, invoke(devMail_1.devMailMessage, { params: { id: record.id } })];
|
|
238
|
+
case 3:
|
|
239
|
+
_b.apply(void 0, [(_d.sent()).status]).toBe(404);
|
|
240
|
+
process.env.DEV_AUTO_LOGIN_EMAIL = ' ';
|
|
241
|
+
_c = expect;
|
|
242
|
+
return [4 /*yield*/, invoke(devMail_1.devMail)];
|
|
243
|
+
case 4:
|
|
244
|
+
_c.apply(void 0, [(_d.sent()).status]).toBe(404);
|
|
245
|
+
return [2 /*return*/];
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}); });
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=DevMail.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DevMail.test.js","sourceRoot":"","sources":["../../test/DevMail.test.ts"],"names":[],"mappings":"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"}
|