@proteinjs/server 3.7.0 → 3.8.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/src/routes/reactApp.d.ts.map +1 -1
- package/dist/src/routes/reactApp.js +24 -6
- package/dist/src/routes/reactApp.js.map +1 -1
- package/dist/src/startServer.js +23 -31
- package/dist/src/startServer.js.map +1 -1
- package/package.json +3 -3
- package/src/routes/reactApp.ts +15 -2
- package/src/startServer.ts +21 -20
- package/test/fixture/gracefulShutdownServer.js +34 -1
- package/test/localStrategy.test.ts +195 -0
- package/test/reactAppHeadTags.test.ts +142 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [3.8.1](https://github.com/proteinjs/server/compare/@proteinjs/server@3.8.0...@proteinjs/server@3.8.1) (2026-09-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* a credential check never ends the process ([f936cb7](https://github.com/proteinjs/server/commit/f936cb7cde2e7aace1fd287f0c12cf06aa543a0b))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [3.8.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.7.0...@proteinjs/server@3.8.0) (2026-09-17)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **server-api:** server-rendered head tags — a ServerRenderedHeadTag loadable rendered into the page's <head> ([816b92e](https://github.com/proteinjs/server/commit/816b92ee1595681db1a9e92a364e0997e82081ad))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [3.7.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.6.0...@proteinjs/server@3.7.0) (2026-09-12)
|
|
7
29
|
|
|
8
30
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAuD,MAAM,uBAAuB,CAAC;AAU1G,eAAO,MAAM,cAAc,iBAAkB,YAAY;;;yBAI1B,GAAG,YAAY,GAAG,KAAG,QAAQ,IAAI,CAAC;CAiDhE,CAAC"}
|
|
@@ -55,7 +55,7 @@ var createReactApp = function (serverConfig) {
|
|
|
55
55
|
path: '*',
|
|
56
56
|
method: 'get',
|
|
57
57
|
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
58
|
-
var helmet, _a, serverRenderedScripts, bundleUrls;
|
|
58
|
+
var helmet, _a, serverRenderedScripts, bundleUrls, headTags;
|
|
59
59
|
var _b, _c, _d;
|
|
60
60
|
return __generator(this, function (_e) {
|
|
61
61
|
switch (_e.label) {
|
|
@@ -70,9 +70,10 @@ var createReactApp = function (serverConfig) {
|
|
|
70
70
|
return [4 /*yield*/, Promise.all([
|
|
71
71
|
serverRenderedScriptTags(),
|
|
72
72
|
bundleScriptUrls(serverConfig),
|
|
73
|
+
serverRenderedHeadTags(request),
|
|
73
74
|
])];
|
|
74
75
|
case 1:
|
|
75
|
-
_a = _e.sent(), serverRenderedScripts = _a[0], bundleUrls = _a[1];
|
|
76
|
+
_a = _e.sent(), serverRenderedScripts = _a[0], bundleUrls = _a[1], headTags = _a[2];
|
|
76
77
|
// The page must ALWAYS revalidate (found live 2026-09-01, the mobile-app stale-page
|
|
77
78
|
// investigation): without an explicit policy, HTTP heuristic caching applies (RFC 9111
|
|
78
79
|
// §4.2.2) — WKWebView in particular can serve the cached page without revalidating,
|
|
@@ -80,7 +81,7 @@ var createReactApp = function (serverConfig) {
|
|
|
80
81
|
// bundles under /static keep their long cache (a fresh page always points at fresh
|
|
81
82
|
// hashes); `no-cache` + the ETag express already stamps = a cheap 304 on every load.
|
|
82
83
|
response.set('Cache-Control', 'no-cache');
|
|
83
|
-
response.send("<!DOCTYPE html>\n <html ".concat(helmet.htmlAttributes, ">\n <head>\n <meta charset='utf-8' />\n <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover'>\n <meta name='theme-color' content='").concat(THEME_COLOR_LIGHT, "' media='(prefers-color-scheme: light)'>\n <meta name='theme-color' content='").concat(THEME_COLOR_DARK, "' media='(prefers-color-scheme: dark)'>\n <link href='").concat(((_d = serverConfig.staticContent) === null || _d === void 0 ? void 0 : _d.faviconPath) ? path_1.default.join('/static/', serverConfig.staticContent.faviconPath) : '', "' rel='icon' type='image/png' />\n ").concat(bundlePreloadTags(bundleUrls), "\n ").concat(helmet.title.toString(), "\n ").concat(helmet.meta.toString(), "\n ").concat(helmet.link.toString(), "\n </head>\n <body ").concat(helmet.bodyAttributes.toString(), ">\n <div id='app'></div>\n <script>proteinjs = {};</script>\n ").concat(serverRenderedScripts, "\n ").concat(bundleScriptTags(bundleUrls), "\n </body>\n </html>"));
|
|
84
|
+
response.send("<!DOCTYPE html>\n <html ".concat(helmet.htmlAttributes, ">\n <head>\n <meta charset='utf-8' />\n <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover'>\n <meta name='theme-color' content='").concat(THEME_COLOR_LIGHT, "' media='(prefers-color-scheme: light)'>\n <meta name='theme-color' content='").concat(THEME_COLOR_DARK, "' media='(prefers-color-scheme: dark)'>\n <link href='").concat(((_d = serverConfig.staticContent) === null || _d === void 0 ? void 0 : _d.faviconPath) ? path_1.default.join('/static/', serverConfig.staticContent.faviconPath) : '', "' rel='icon' type='image/png' />\n ").concat(bundlePreloadTags(bundleUrls), "\n ").concat(helmet.title.toString(), "\n ").concat(helmet.meta.toString(), "\n ").concat(helmet.link.toString(), "\n ").concat(headTags, "\n </head>\n <body ").concat(helmet.bodyAttributes.toString(), ">\n <div id='app'></div>\n <script>proteinjs = {};</script>\n ").concat(serverRenderedScripts, "\n ").concat(bundleScriptTags(bundleUrls), "\n </body>\n </html>"));
|
|
84
85
|
return [2 /*return*/];
|
|
85
86
|
}
|
|
86
87
|
});
|
|
@@ -123,9 +124,7 @@ function bundleScriptUrls(serverConfig) {
|
|
|
123
124
|
return [4 /*yield*/, util_node_1.Fs.getFilePathsMatchingGlob(resolvedBundlesDir, '**/*.js')];
|
|
124
125
|
case 1:
|
|
125
126
|
filePaths = _f.sent();
|
|
126
|
-
return [2 /*return*/, filePaths
|
|
127
|
-
.map(function (filePath) { return path_1.default.join('/static/', path_1.default.relative(staticContentDir_1, filePath)); })
|
|
128
|
-
.sort()];
|
|
127
|
+
return [2 /*return*/, filePaths.map(function (filePath) { return path_1.default.join('/static/', path_1.default.relative(staticContentDir_1, filePath)); }).sort()];
|
|
129
128
|
case 2: return [2 /*return*/, []];
|
|
130
129
|
}
|
|
131
130
|
});
|
|
@@ -161,4 +160,23 @@ function serverRenderedScriptTags() {
|
|
|
161
160
|
});
|
|
162
161
|
});
|
|
163
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Every server-rendered head tag rendered CONCURRENTLY for this request (the same one round the
|
|
165
|
+
* scripts ride); emitted in registration order, an empty render dropped.
|
|
166
|
+
*/
|
|
167
|
+
function serverRenderedHeadTags(request) {
|
|
168
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
169
|
+
var tags, rendered;
|
|
170
|
+
return __generator(this, function (_a) {
|
|
171
|
+
switch (_a.label) {
|
|
172
|
+
case 0:
|
|
173
|
+
tags = (0, server_api_1.getServerRenderedHeadTags)();
|
|
174
|
+
return [4 /*yield*/, Promise.all(tags.map(function (tag) { return tag.headTag(request); }))];
|
|
175
|
+
case 1:
|
|
176
|
+
rendered = _a.sent();
|
|
177
|
+
return [2 /*return*/, rendered.filter(function (tag) { return tag.length > 0; }).join('\n')];
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
}
|
|
164
182
|
//# sourceMappingURL=reactApp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactApp.js","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAwB;
|
|
1
|
+
{"version":3,"file":"reactApp.js","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"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"}
|
package/dist/src/startServer.js
CHANGED
|
@@ -382,21 +382,38 @@ function configureSession(app, config) {
|
|
|
382
382
|
initializeAuthentication(config.authenticate);
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
|
+
/**
|
|
386
|
+
* Registers the local strategy over the consumer's credential check, for consumer routes to drive
|
|
387
|
+
* (`passport.authenticate('local')`). The framework never runs it on a request of its own: the
|
|
388
|
+
* strategy fires on ANY request whose body or query carries its `username` and `password` fields,
|
|
389
|
+
* whatever the path — a credential check belongs to the route that asked for it.
|
|
390
|
+
*/
|
|
385
391
|
function initializeAuthentication(authenticate) {
|
|
386
392
|
passport_1.default.use(new passport_local_1.default.Strategy(function (username, password, done) {
|
|
387
393
|
return __awaiter(this, void 0, void 0, function () {
|
|
388
|
-
var result;
|
|
394
|
+
var result, error_1;
|
|
389
395
|
return __generator(this, function (_a) {
|
|
390
396
|
switch (_a.label) {
|
|
391
397
|
case 0:
|
|
392
398
|
logger.info({ message: "Authenticating" });
|
|
393
|
-
|
|
399
|
+
_a.label = 1;
|
|
394
400
|
case 1:
|
|
401
|
+
_a.trys.push([1, 3, , 4]);
|
|
402
|
+
return [4 /*yield*/, authenticate(username, password)];
|
|
403
|
+
case 2:
|
|
395
404
|
result = _a.sent();
|
|
405
|
+
return [3 /*break*/, 4];
|
|
406
|
+
case 3:
|
|
407
|
+
error_1 = _a.sent();
|
|
408
|
+
done(error_1);
|
|
409
|
+
return [2 /*return*/];
|
|
410
|
+
case 4:
|
|
396
411
|
if (result === true) {
|
|
397
|
-
|
|
412
|
+
done(null, { username: username });
|
|
413
|
+
return [2 /*return*/];
|
|
398
414
|
}
|
|
399
|
-
|
|
415
|
+
done(null, false, { message: result });
|
|
416
|
+
return [2 /*return*/];
|
|
400
417
|
}
|
|
401
418
|
});
|
|
402
419
|
});
|
|
@@ -411,33 +428,8 @@ function initializeAuthentication(authenticate) {
|
|
|
411
428
|
});
|
|
412
429
|
}
|
|
413
430
|
function beforeRequest(app, config) {
|
|
414
|
-
var
|
|
415
|
-
|
|
416
|
-
if (((_a = config.request) === null || _a === void 0 ? void 0 : _a.disableRequestLogging) == false || typeof ((_b = config.request) === null || _b === void 0 ? void 0 : _b.disableRequestLogging) === 'undefined') {
|
|
417
|
-
app.use(function (request, response, next) { return __awaiter(_this, void 0, void 0, function () {
|
|
418
|
-
return __generator(this, function (_a) {
|
|
419
|
-
switch (_a.label) {
|
|
420
|
-
case 0:
|
|
421
|
-
if (!config.authenticate) return [3 /*break*/, 2];
|
|
422
|
-
return [4 /*yield*/, new Promise(function (resolve, reject) {
|
|
423
|
-
passport_1.default.authenticate('local', function (err) {
|
|
424
|
-
if (err) {
|
|
425
|
-
reject(err);
|
|
426
|
-
}
|
|
427
|
-
resolve();
|
|
428
|
-
})(request, response, next);
|
|
429
|
-
})];
|
|
430
|
-
case 1:
|
|
431
|
-
_a.sent();
|
|
432
|
-
_a.label = 2;
|
|
433
|
-
case 2:
|
|
434
|
-
next();
|
|
435
|
-
return [2 /*return*/];
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
}); });
|
|
439
|
-
}
|
|
440
|
-
if ((_c = config.request) === null || _c === void 0 ? void 0 : _c.beforeRequest) {
|
|
431
|
+
var _a;
|
|
432
|
+
if ((_a = config.request) === null || _a === void 0 ? void 0 : _a.beforeRequest) {
|
|
441
433
|
app.use(config.request.beforeRequest);
|
|
442
434
|
}
|
|
443
435
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.1",
|
|
4
4
|
"description": "A server impl",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@proteinjs/event": "^1.0.18",
|
|
26
26
|
"@proteinjs/logger": "^1.0.21",
|
|
27
27
|
"@proteinjs/reflection": "^1.1.12",
|
|
28
|
-
"@proteinjs/server-api": "^3.
|
|
28
|
+
"@proteinjs/server-api": "^3.3.0",
|
|
29
29
|
"@proteinjs/util-node": "^1.10.1",
|
|
30
30
|
"body-parser": "1.19.0",
|
|
31
31
|
"cookie-parser": "1.4.5",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
},
|
|
65
65
|
"main": "./dist/generated/index.js",
|
|
66
66
|
"types": "./dist/generated/index.d.ts",
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "c70a36a3e79224b254dcd9010518b16586c22f48"
|
|
68
68
|
}
|
package/src/routes/reactApp.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import express from 'express';
|
|
2
3
|
import ReactHelmet from 'react-helmet';
|
|
3
|
-
import { ServerConfig, getServerRenderedScripts } from '@proteinjs/server-api';
|
|
4
|
+
import { ServerConfig, getServerRenderedHeadTags, getServerRenderedScripts } from '@proteinjs/server-api';
|
|
4
5
|
import { Fs } from '@proteinjs/util-node';
|
|
5
6
|
import { DevClientBuild } from '../DevClientBuild';
|
|
6
7
|
|
|
@@ -28,9 +29,10 @@ export const createReactApp = (serverConfig: ServerConfig) => {
|
|
|
28
29
|
// and the bundle listing run concurrently — the page's TTFB is the SLOWEST of them, not their
|
|
29
30
|
// sum (measured on a phone: 5–6 reads awaited one after another sat in front of every byte
|
|
30
31
|
// of the page).
|
|
31
|
-
const [serverRenderedScripts, bundleUrls] = await Promise.all([
|
|
32
|
+
const [serverRenderedScripts, bundleUrls, headTags] = await Promise.all([
|
|
32
33
|
serverRenderedScriptTags(),
|
|
33
34
|
bundleScriptUrls(serverConfig),
|
|
35
|
+
serverRenderedHeadTags(request),
|
|
34
36
|
]);
|
|
35
37
|
// The page must ALWAYS revalidate (found live 2026-09-01, the mobile-app stale-page
|
|
36
38
|
// investigation): without an explicit policy, HTTP heuristic caching applies (RFC 9111
|
|
@@ -51,6 +53,7 @@ export const createReactApp = (serverConfig: ServerConfig) => {
|
|
|
51
53
|
${helmet.title.toString()}
|
|
52
54
|
${helmet.meta.toString()}
|
|
53
55
|
${helmet.link.toString()}
|
|
56
|
+
${headTags}
|
|
54
57
|
</head>
|
|
55
58
|
<body ${helmet.bodyAttributes.toString()}>
|
|
56
59
|
<div id='app'></div>
|
|
@@ -121,3 +124,13 @@ async function serverRenderedScriptTags(): Promise<string> {
|
|
|
121
124
|
const rendered = await Promise.all(scripts.map((script) => script.script()));
|
|
122
125
|
return rendered.map((script) => `<script>${script}</script>`).join('\n');
|
|
123
126
|
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Every server-rendered head tag rendered CONCURRENTLY for this request (the same one round the
|
|
130
|
+
* scripts ride); emitted in registration order, an empty render dropped.
|
|
131
|
+
*/
|
|
132
|
+
async function serverRenderedHeadTags(request: express.Request): Promise<string> {
|
|
133
|
+
const tags = getServerRenderedHeadTags();
|
|
134
|
+
const rendered = await Promise.all(tags.map((tag) => tag.headTag(request)));
|
|
135
|
+
return rendered.filter((tag) => tag.length > 0).join('\n');
|
|
136
|
+
}
|
package/src/startServer.ts
CHANGED
|
@@ -338,16 +338,34 @@ function configureSession(app: express.Express, config: ServerConfig) {
|
|
|
338
338
|
}
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Registers the local strategy over the consumer's credential check, for consumer routes to drive
|
|
343
|
+
* (`passport.authenticate('local')`). The framework never runs it on a request of its own: the
|
|
344
|
+
* strategy fires on ANY request whose body or query carries its `username` and `password` fields,
|
|
345
|
+
* whatever the path — a credential check belongs to the route that asked for it.
|
|
346
|
+
*/
|
|
341
347
|
function initializeAuthentication(authenticate: (username: string, password: string) => Promise<true | string>) {
|
|
342
348
|
passport.use(
|
|
343
349
|
new passportLocal.Strategy(async function (username, password, done) {
|
|
344
350
|
logger.info({ message: `Authenticating` });
|
|
345
|
-
|
|
351
|
+
// Passport does not await this callback, so it settles through `done` on every path — a
|
|
352
|
+
// rejection here is nobody's to catch and ends the process. A failed check (the reason, as
|
|
353
|
+
// a string) is a passport FAILURE, answered 401; a check that could not run is a passport
|
|
354
|
+
// ERROR, handed to the pipeline.
|
|
355
|
+
let result: true | string;
|
|
356
|
+
try {
|
|
357
|
+
result = await authenticate(username, password);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
done(error);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
346
363
|
if (result === true) {
|
|
347
|
-
|
|
364
|
+
done(null, { username });
|
|
365
|
+
return;
|
|
348
366
|
}
|
|
349
367
|
|
|
350
|
-
|
|
368
|
+
done(null, false, { message: result });
|
|
351
369
|
})
|
|
352
370
|
);
|
|
353
371
|
|
|
@@ -363,23 +381,6 @@ function initializeAuthentication(authenticate: (username: string, password: str
|
|
|
363
381
|
}
|
|
364
382
|
|
|
365
383
|
function beforeRequest(app: express.Express, config: ServerConfig) {
|
|
366
|
-
if (config.request?.disableRequestLogging == false || typeof config.request?.disableRequestLogging === 'undefined') {
|
|
367
|
-
app.use(async (request: express.Request, response: express.Response, next: express.NextFunction) => {
|
|
368
|
-
if (config.authenticate) {
|
|
369
|
-
await new Promise<void>((resolve, reject) => {
|
|
370
|
-
passport.authenticate('local', function (err: unknown) {
|
|
371
|
-
if (err) {
|
|
372
|
-
reject(err);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
resolve();
|
|
376
|
-
})(request, response, next);
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
next();
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
|
|
383
384
|
if (config.request?.beforeRequest) {
|
|
384
385
|
app.use(config.request.beforeRequest);
|
|
385
386
|
}
|
|
@@ -15,8 +15,13 @@
|
|
|
15
15
|
* Also serves /server-timeouts: the LIVE http.Server's keepAliveTimeout/headersTimeout (read off
|
|
16
16
|
* the request's own socket), so the keep-alive suite asserts the running instance through the
|
|
17
17
|
* front door instead of re-deriving values from source.
|
|
18
|
+
*
|
|
19
|
+
* Also serves the local-strategy suite: /served, a route any request reaches (one carrying the
|
|
20
|
+
* strategy's `username` + `password` fields included), and /local-strategy, a consumer route
|
|
21
|
+
* driving the registered strategy the passport way (`passport.authenticate('local')`).
|
|
18
22
|
*/
|
|
19
23
|
const expressSession = require('express-session');
|
|
24
|
+
const passport = require('passport');
|
|
20
25
|
const { startServer, GracefulShutdown } = require('../../dist/generated/index.js');
|
|
21
26
|
|
|
22
27
|
const port = Number(process.env.FIXTURE_PORT);
|
|
@@ -27,8 +32,17 @@ if (!port) {
|
|
|
27
32
|
startServer({
|
|
28
33
|
port,
|
|
29
34
|
session: { secret: 'graceful-shutdown-test', store: new expressSession.MemoryStore() },
|
|
35
|
+
// The credential check every consumer configures, in the three shapes the local-strategy suite
|
|
36
|
+
// drives: a right password passes, a wrong one is a failed check (the reason), and the name
|
|
37
|
+
// `unavailable` is a check that fails outright (a rejection).
|
|
38
|
+
authenticate: async (username, password) => {
|
|
39
|
+
if (username === 'unavailable') {
|
|
40
|
+
throw new Error('credential store unavailable');
|
|
41
|
+
}
|
|
42
|
+
return password === 'right' ? true : 'wrong password';
|
|
43
|
+
},
|
|
44
|
+
// Request logging stays ON — the served shape; the suites read their own markers off stdout.
|
|
30
45
|
request: {
|
|
31
|
-
disableRequestLogging: true,
|
|
32
46
|
// The slow endpoint rides the beforeRequest middleware seam so the fixture needs no
|
|
33
47
|
// reflection-registered Route of its own: it answers /slow itself (never calls next)
|
|
34
48
|
// after ?ms= of held work, standing in for any long in-flight request.
|
|
@@ -62,6 +76,25 @@ startServer({
|
|
|
62
76
|
response.status(200).send('held');
|
|
63
77
|
return;
|
|
64
78
|
}
|
|
79
|
+
if (request.path === '/served') {
|
|
80
|
+
// A route like any other: the framework serves the request whatever fields it carries —
|
|
81
|
+
// the route decides what credentials mean, if anything.
|
|
82
|
+
response.status(200).send('served');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (request.path === '/local-strategy') {
|
|
86
|
+
// A consumer route driving the registered strategy the passport way: passport's own
|
|
87
|
+
// answers (401 for a failed check, a session for a passed one, next(error) for a failing
|
|
88
|
+
// one) are the contract.
|
|
89
|
+
passport.authenticate('local')(request, response, (error) => {
|
|
90
|
+
if (error) {
|
|
91
|
+
next(error);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
response.status(200).send(`logged in as ${request.user.username}`);
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
65
98
|
if (request.path !== '/slow') {
|
|
66
99
|
next();
|
|
67
100
|
return;
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import * as net from 'net';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { ChildProcess, spawn } from 'child_process';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Local-strategy contract of a real server process (spawns the built dist — run `npm run build`
|
|
8
|
+
* first), asserted through the front door.
|
|
9
|
+
*
|
|
10
|
+
* THE CLASS THIS PINS: a credential check never ends the process. When an `authenticate` function
|
|
11
|
+
* is configured the framework registers a passport local strategy, and that strategy fires on any
|
|
12
|
+
* request whose body or query carries its `username` and `password` fields — whatever the path.
|
|
13
|
+
* The framework itself never runs the check on a request: such a request reaches its route like
|
|
14
|
+
* any other, and the process is there to serve the next one. A consumer route that drives the
|
|
15
|
+
* strategy (`passport.authenticate('local')`) gets passport's own answers — a wrong password is a
|
|
16
|
+
* FAILURE (401), a right one a session, a failing check an ERROR (500) — never a rejection nobody
|
|
17
|
+
* awaits.
|
|
18
|
+
*/
|
|
19
|
+
const packageRoot = path.join(__dirname, '..');
|
|
20
|
+
const fixturePath = path.join(__dirname, 'fixture', 'gracefulShutdownServer.js');
|
|
21
|
+
|
|
22
|
+
describe('the local strategy through the front door', () => {
|
|
23
|
+
let fixture: Fixture | undefined;
|
|
24
|
+
|
|
25
|
+
afterEach(async () => {
|
|
26
|
+
if (fixture && fixture.child.exitCode === null && fixture.child.signalCode === null) {
|
|
27
|
+
fixture.child.kill('SIGKILL');
|
|
28
|
+
await fixture.exited.catch(() => undefined);
|
|
29
|
+
}
|
|
30
|
+
fixture = undefined;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('a request carrying the strategy fields in the QUERY with a wrong password reaches its route; the process serves the next request', async () => {
|
|
34
|
+
fixture = await startFixture();
|
|
35
|
+
|
|
36
|
+
const outcome = await requestAndProcess(fixture, {
|
|
37
|
+
method: 'GET',
|
|
38
|
+
path: '/served?username=someone&password=wrong',
|
|
39
|
+
});
|
|
40
|
+
expect(outcome).toEqual({ served: { status: 200, body: 'served' }, process: 'alive' });
|
|
41
|
+
|
|
42
|
+
const next = await request(fixture.port, { method: 'GET', path: '/health-check' });
|
|
43
|
+
expect(next.status).toBe(200);
|
|
44
|
+
}, 30000);
|
|
45
|
+
|
|
46
|
+
it('a request carrying the strategy fields in a JSON BODY with a wrong password reaches its route; the process serves the next request', async () => {
|
|
47
|
+
fixture = await startFixture();
|
|
48
|
+
|
|
49
|
+
const outcome = await requestAndProcess(fixture, {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
path: '/served',
|
|
52
|
+
json: { username: 'someone', password: 'wrong' },
|
|
53
|
+
});
|
|
54
|
+
expect(outcome).toEqual({ served: { status: 200, body: 'served' }, process: 'alive' });
|
|
55
|
+
|
|
56
|
+
const next = await request(fixture.port, { method: 'GET', path: '/health-check' });
|
|
57
|
+
expect(next.status).toBe(200);
|
|
58
|
+
}, 30000);
|
|
59
|
+
|
|
60
|
+
it('a consumer route driving the strategy: a wrong password is refused 401, a right one is logged in', async () => {
|
|
61
|
+
fixture = await startFixture();
|
|
62
|
+
|
|
63
|
+
const wrong = await request(fixture.port, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
path: '/local-strategy',
|
|
66
|
+
json: { username: 'someone', password: 'wrong' },
|
|
67
|
+
});
|
|
68
|
+
expect(wrong.status).toBe(401);
|
|
69
|
+
|
|
70
|
+
const right = await request(fixture.port, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
path: '/local-strategy',
|
|
73
|
+
json: { username: 'someone', password: 'right' },
|
|
74
|
+
});
|
|
75
|
+
expect(right).toMatchObject({ status: 200, body: 'logged in as someone' });
|
|
76
|
+
}, 30000);
|
|
77
|
+
|
|
78
|
+
it('a consumer route driving the strategy: a failing credential check is answered 500; the process serves the next request', async () => {
|
|
79
|
+
fixture = await startFixture();
|
|
80
|
+
|
|
81
|
+
const outcome = await requestAndProcess(fixture, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
path: '/local-strategy',
|
|
84
|
+
json: { username: 'unavailable', password: 'right' },
|
|
85
|
+
});
|
|
86
|
+
expect(outcome).toEqual({ served: expect.objectContaining({ status: 500 }), process: 'alive' });
|
|
87
|
+
|
|
88
|
+
const next = await request(fixture.port, { method: 'GET', path: '/health-check' });
|
|
89
|
+
expect(next.status).toBe(200);
|
|
90
|
+
}, 30000);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
type Fixture = {
|
|
94
|
+
child: ChildProcess;
|
|
95
|
+
port: number;
|
|
96
|
+
output: () => string;
|
|
97
|
+
exited: Promise<{ code: number | null; signal: NodeJS.Signals | null }>;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
async function startFixture(): Promise<Fixture> {
|
|
101
|
+
const port = await ephemeralPort();
|
|
102
|
+
// Scrub the env vars startServer reads (dev machines export some of these): the fixture's
|
|
103
|
+
// behavior must come from its own config only.
|
|
104
|
+
const env = { ...process.env };
|
|
105
|
+
delete env.SERVER_PORT;
|
|
106
|
+
delete env.DEVELOPMENT;
|
|
107
|
+
delete env.DISABLE_HOT_CLIENT_BUILDS;
|
|
108
|
+
delete env.HMR_PORT;
|
|
109
|
+
const child = spawn(process.execPath, [fixturePath], {
|
|
110
|
+
cwd: packageRoot,
|
|
111
|
+
env: { ...env, FIXTURE_PORT: String(port) },
|
|
112
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
113
|
+
});
|
|
114
|
+
let output = '';
|
|
115
|
+
child.stdout!.on('data', (chunk) => (output += String(chunk)));
|
|
116
|
+
child.stderr!.on('data', (chunk) => (output += String(chunk)));
|
|
117
|
+
const exited = new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((resolve) =>
|
|
118
|
+
child.once('exit', (code, signal) => resolve({ code, signal }))
|
|
119
|
+
);
|
|
120
|
+
// Ready = the health check answers 200 (readiness through the front door, not log lines).
|
|
121
|
+
const deadline = Date.now() + 20000;
|
|
122
|
+
for (;;) {
|
|
123
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
124
|
+
throw new Error(`Fixture exited during boot; output:\n${output}`);
|
|
125
|
+
}
|
|
126
|
+
const result = await request(port, { method: 'GET', path: '/health-check' }).catch(() => undefined);
|
|
127
|
+
if (result?.status === 200) {
|
|
128
|
+
return { child, port, output: () => output, exited };
|
|
129
|
+
}
|
|
130
|
+
if (Date.now() > deadline) {
|
|
131
|
+
throw new Error(`Fixture never became ready; output:\n${output}`);
|
|
132
|
+
}
|
|
133
|
+
await sleep(100);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* One request, and what became of the process that served it: the answer (or the failure the
|
|
139
|
+
* client saw), and whether the process is still there afterwards — a process the request ended
|
|
140
|
+
* has exited by then; one that lives is still running 300ms later.
|
|
141
|
+
*/
|
|
142
|
+
async function requestAndProcess(fixture: Fixture, options: RequestOptions) {
|
|
143
|
+
const served = await request(fixture.port, options).then(
|
|
144
|
+
({ status, body }) => ({ status, body }),
|
|
145
|
+
(error: Error) => ({ failed: error.message })
|
|
146
|
+
);
|
|
147
|
+
const process = await Promise.race([
|
|
148
|
+
fixture.exited.then((exit) => ({ exited: exit, output: fixture.output() })),
|
|
149
|
+
sleep(300).then(() => 'alive' as const),
|
|
150
|
+
]);
|
|
151
|
+
return { served, process };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type RequestOptions = { method: string; path: string; headers?: Record<string, string>; json?: unknown };
|
|
155
|
+
|
|
156
|
+
/** One request on its OWN connection (agent: false — no keep-alive pooling). */
|
|
157
|
+
function request(
|
|
158
|
+
port: number,
|
|
159
|
+
options: RequestOptions
|
|
160
|
+
): Promise<{ status: number; body: string; headers: http.IncomingHttpHeaders }> {
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const payload = options.json === undefined ? undefined : JSON.stringify(options.json);
|
|
163
|
+
const headers: Record<string, string> = { ...options.headers };
|
|
164
|
+
if (payload !== undefined) {
|
|
165
|
+
headers['Content-Type'] = 'application/json';
|
|
166
|
+
headers['Content-Length'] = String(Buffer.byteLength(payload));
|
|
167
|
+
}
|
|
168
|
+
const req = http.request(
|
|
169
|
+
{ host: '127.0.0.1', port, method: options.method, path: options.path, agent: false, headers },
|
|
170
|
+
(res) => {
|
|
171
|
+
let body = '';
|
|
172
|
+
res.on('data', (chunk) => (body += String(chunk)));
|
|
173
|
+
res.on('end', () => resolve({ status: res.statusCode ?? 0, body, headers: res.headers }));
|
|
174
|
+
res.on('error', reject);
|
|
175
|
+
}
|
|
176
|
+
);
|
|
177
|
+
req.on('error', reject);
|
|
178
|
+
req.end(payload);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function ephemeralPort(): Promise<number> {
|
|
183
|
+
return new Promise((resolve, reject) => {
|
|
184
|
+
const probe = net.createServer();
|
|
185
|
+
probe.once('error', reject);
|
|
186
|
+
probe.listen(0, '127.0.0.1', () => {
|
|
187
|
+
const address = probe.address() as net.AddressInfo;
|
|
188
|
+
probe.close(() => resolve(address.port));
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function sleep(ms: number): Promise<void> {
|
|
194
|
+
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
195
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Server-rendered HEAD tags (`ServerRenderedHeadTag`): the head counterpart of the server-rendered
|
|
7
|
+
* scripts. A browser reads some tags at parse time — a `<meta>` the client bundle would inject too
|
|
8
|
+
* late — so the page carries them in the served document:
|
|
9
|
+
*
|
|
10
|
+
* 1. every registered tag lands inside `<head>`, in registration order, rendered concurrently in
|
|
11
|
+
* the page's ONE boot round (started before any resolves, like the scripts);
|
|
12
|
+
* 2. the request is handed to each tag, so a tag can name the page being served;
|
|
13
|
+
* 3. an empty render is dropped — nothing for this request, no blank line left behind.
|
|
14
|
+
*/
|
|
15
|
+
const scripts: { script: () => Promise<string> }[] = [];
|
|
16
|
+
const headTags: { headTag: (request: unknown) => Promise<string> }[] = [];
|
|
17
|
+
jest.mock('@proteinjs/server-api', () => ({
|
|
18
|
+
...jest.requireActual('@proteinjs/server-api'),
|
|
19
|
+
getServerRenderedScripts: () => scripts,
|
|
20
|
+
getServerRenderedHeadTags: () => headTags,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
import { createReactApp } from '../src/routes/reactApp';
|
|
24
|
+
|
|
25
|
+
type Rendered = { headers: Record<string, string>; html: string };
|
|
26
|
+
|
|
27
|
+
function renderInto(rendered: Rendered, staticContent: Record<string, unknown>, request: unknown): Promise<void> {
|
|
28
|
+
const response = {
|
|
29
|
+
set: (name: string, value: string) => {
|
|
30
|
+
rendered.headers[name] = value;
|
|
31
|
+
},
|
|
32
|
+
send: (html: string) => {
|
|
33
|
+
rendered.html = html;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
return createReactApp({ staticContent } as any).onRequest(request, response);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function render(staticContent: Record<string, unknown>, request: unknown = { path: '/' }): Promise<Rendered> {
|
|
40
|
+
const rendered: Rendered = { headers: {}, html: '' };
|
|
41
|
+
await renderInto(rendered, staticContent, request);
|
|
42
|
+
return rendered;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const flushMicrotasks = async () => {
|
|
46
|
+
for (let i = 0; i < 10; i++) {
|
|
47
|
+
await Promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const headOf = (html: string) => html.slice(html.indexOf('<head>'), html.indexOf('</head>'));
|
|
52
|
+
|
|
53
|
+
describe('server-rendered head tags', () => {
|
|
54
|
+
let tmp: string;
|
|
55
|
+
const env = {
|
|
56
|
+
DEVELOPMENT: process.env.DEVELOPMENT,
|
|
57
|
+
DISABLE_HOT_CLIENT_BUILDS: process.env.DISABLE_HOT_CLIENT_BUILDS,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
scripts.length = 0;
|
|
62
|
+
headTags.length = 0;
|
|
63
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'react-app-head-'));
|
|
64
|
+
fs.mkdirSync(path.join(tmp, 'bundles'));
|
|
65
|
+
fs.writeFileSync(path.join(tmp, 'bundles', 'app.js'), '');
|
|
66
|
+
delete process.env.DEVELOPMENT;
|
|
67
|
+
delete process.env.DISABLE_HOT_CLIENT_BUILDS;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
72
|
+
for (const [name, value] of Object.entries(env)) {
|
|
73
|
+
if (value === undefined) {
|
|
74
|
+
delete process.env[name];
|
|
75
|
+
} else {
|
|
76
|
+
process.env[name] = value;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const staticContent = () => ({ staticContentDir: tmp, bundlesDir: 'bundles' });
|
|
82
|
+
|
|
83
|
+
it('renders every tag inside <head>, in registration order, handing each the request', async () => {
|
|
84
|
+
headTags.push(
|
|
85
|
+
{ headTag: async (request: any) => `<meta name="page" content="${request.originalUrl}">` },
|
|
86
|
+
{ headTag: async () => `<link rel="manifest" href="/manifest.json">` }
|
|
87
|
+
);
|
|
88
|
+
const { html } = await render(staticContent(), { path: '/', originalUrl: '/things?id=7' });
|
|
89
|
+
const head = headOf(html);
|
|
90
|
+
expect(head).toContain('<meta name="page" content="/things?id=7">');
|
|
91
|
+
expect(head).toContain('<link rel="manifest" href="/manifest.json">');
|
|
92
|
+
expect(head.indexOf('<meta name="page"')).toBeLessThan(head.indexOf('<link rel="manifest"'));
|
|
93
|
+
// Never in the body.
|
|
94
|
+
expect(html.slice(html.indexOf('<body'))).not.toContain('<meta name="page"');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('drops an empty render — nothing for this request leaves nothing behind', async () => {
|
|
98
|
+
const blankLines = (head: string) => head.split('\n').filter((line) => line.trim() === '').length;
|
|
99
|
+
headTags.push({ headTag: async () => '<meta name="only" content="1">' });
|
|
100
|
+
const alone = blankLines(headOf((await render(staticContent())).html));
|
|
101
|
+
|
|
102
|
+
headTags.unshift({ headTag: async () => '' });
|
|
103
|
+
const { html } = await render(staticContent());
|
|
104
|
+
const head = headOf(html);
|
|
105
|
+
expect(head).toContain('<meta name="only" content="1">');
|
|
106
|
+
// The empty render added no line of its own: the head carries exactly the blank lines it
|
|
107
|
+
// carries with the one tag alone (an unfiltered empty would join as a stray newline).
|
|
108
|
+
expect(blankLines(head)).toBe(alone);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('a page with no registered tags renders exactly as before', async () => {
|
|
112
|
+
const { html } = await render(staticContent());
|
|
113
|
+
expect(html).toContain('<head>');
|
|
114
|
+
expect(html).not.toContain('undefined');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('starts every tag before any resolves — the one boot round the scripts ride', async () => {
|
|
118
|
+
const started: string[] = [];
|
|
119
|
+
const release: Record<string, () => void> = {};
|
|
120
|
+
const gated = (name: string) => ({
|
|
121
|
+
headTag: () =>
|
|
122
|
+
new Promise<string>((resolve) => {
|
|
123
|
+
started.push(name);
|
|
124
|
+
release[name] = () => resolve(`<meta name="${name}">`);
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
headTags.push(gated('a'), gated('b'));
|
|
128
|
+
scripts.push({ script: async () => (started.push('script'), 'window.s = 1;') });
|
|
129
|
+
|
|
130
|
+
const rendered: Rendered = { headers: {}, html: '' };
|
|
131
|
+
const done = renderInto(rendered, staticContent(), { path: '/' });
|
|
132
|
+
await flushMicrotasks();
|
|
133
|
+
expect(started).toEqual(['script', 'a', 'b']);
|
|
134
|
+
expect(rendered.html).toBe('');
|
|
135
|
+
release.b();
|
|
136
|
+
await flushMicrotasks();
|
|
137
|
+
release.a();
|
|
138
|
+
await done;
|
|
139
|
+
const head = headOf(rendered.html);
|
|
140
|
+
expect(head.indexOf('<meta name="a">')).toBeLessThan(head.indexOf('<meta name="b">'));
|
|
141
|
+
});
|
|
142
|
+
});
|