@tumbaland/backend-core 1.52.0 → 1.54.0
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/dist/app/createBaseApp.d.ts.map +1 -1
- package/dist/app/createBaseApp.js +2 -0
- package/dist/app/createBaseApp.js.map +1 -1
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +22 -3
- package/dist/auth/session.js.map +1 -1
- package/dist/database/connection.d.ts +28 -0
- package/dist/database/connection.d.ts.map +1 -1
- package/dist/database/connection.js +59 -1
- package/dist/database/connection.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/middleware/authMiddleware.d.ts.map +1 -1
- package/dist/middleware/authMiddleware.js +9 -2
- package/dist/middleware/authMiddleware.js.map +1 -1
- package/dist/middleware/corsMiddleware.d.ts.map +1 -1
- package/dist/middleware/corsMiddleware.js +5 -0
- package/dist/middleware/corsMiddleware.js.map +1 -1
- package/dist/middleware/serverTiming.d.ts +9 -0
- package/dist/middleware/serverTiming.d.ts.map +1 -0
- package/dist/middleware/serverTiming.js +50 -0
- package/dist/middleware/serverTiming.js.map +1 -0
- package/dist/tracing/index.d.ts.map +1 -1
- package/dist/tracing/index.js +12 -5
- package/dist/tracing/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBaseApp.d.ts","sourceRoot":"","sources":["../../src/app/createBaseApp.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"createBaseApp.d.ts","sourceRoot":"","sources":["../../src/app/createBaseApp.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAM3D,OAAO,EAAwB,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAI3F,MAAM,WAAW,oBAAoB;IACnC,8CAA8C;IAC9C,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,cAAc,GAAG,KAAK,CAAC;IACrC,4IAA4I;IAC5I,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6FAA6F;IAC7F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kHAAkH;IAClH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CA4BzE"}
|
|
@@ -9,6 +9,7 @@ const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
|
9
9
|
const correlation_1 = require("../utils/correlation");
|
|
10
10
|
const tracing_1 = require("../tracing");
|
|
11
11
|
const requestLogger_1 = require("../middleware/requestLogger");
|
|
12
|
+
const serverTiming_1 = require("../middleware/serverTiming");
|
|
12
13
|
const corsMiddleware_1 = require("../middleware/corsMiddleware");
|
|
13
14
|
const security_1 = require("../middleware/security");
|
|
14
15
|
const healthController_1 = require("../health/healthController");
|
|
@@ -63,6 +64,7 @@ function createBaseApp(options = {}) {
|
|
|
63
64
|
if (tracing)
|
|
64
65
|
app.use(tracing_1.tracingMiddleware);
|
|
65
66
|
app.use(metrics ? requestLogger_1.requestLoggerWithMetrics : requestLogger_1.requestLogger);
|
|
67
|
+
app.use((0, serverTiming_1.slowRequestLogger)());
|
|
66
68
|
app.use((0, corsMiddleware_1.createCorsMiddleware)(corsOptions));
|
|
67
69
|
if (parseCookies)
|
|
68
70
|
app.use((0, cookie_parser_1.default)());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBaseApp.js","sourceRoot":"","sources":["../../src/app/createBaseApp.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"createBaseApp.js","sourceRoot":"","sources":["../../src/app/createBaseApp.ts"],"names":[],"mappings":";;;;;AA2EA,sCA4BC;AAvGD,sDAA2D;AAC3D,kEAAyC;AACzC,sDAA6D;AAC7D,wCAA+C;AAC/C,+DAAsF;AACtF,6DAA+D;AAC/D,iEAA2F;AAC3F,qDAA8E;AAC9E,iEAAwD;AA4BxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,SAAgB,aAAa,CAAC,UAAgC,EAAE;IAC9D,MAAM,EACJ,WAAW,EACX,WAAW,GAAG,8BAAmB,EACjC,SAAS,GAAG,IAAI,EAChB,YAAY,GAAG,IAAI,EACnB,OAAO,GAAG,IAAI,EACd,OAAO,GAAG,IAAI,EACd,UAAU,GAAG,kCAAkC,EAChD,GAAG,OAAO,CAAC;IAEZ,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;IAEtB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAEnC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,6BAAU,CAAC,CAAC;IAEpC,GAAG,CAAC,GAAG,CAAC,0BAAe,CAAC,CAAC;IACzB,IAAI,WAAW;QAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACtC,GAAG,CAAC,GAAG,CAAC,mCAAqB,CAAC,CAAC;IAC/B,IAAI,OAAO;QAAE,GAAG,CAAC,GAAG,CAAC,2BAAiB,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwB,CAAC,CAAC,CAAC,6BAAa,CAAC,CAAC;IAC5D,GAAG,CAAC,GAAG,CAAC,IAAA,gCAAiB,GAAE,CAAC,CAAC;IAC7B,GAAG,CAAC,GAAG,CAAC,IAAA,qCAAoB,EAAC,WAAW,CAAC,CAAC,CAAC;IAC3C,IAAI,YAAY;QAAE,GAAG,CAAC,GAAG,CAAC,IAAA,uBAAY,GAAE,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvC,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAIxD,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAIxD,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAmD1D,eAAO,MAAM,gBAAgB,GAAI,QAAQ,OAAO,KAAG,OAAO,CAAC,OAAO,CAAyB,CAAC;AAE5F;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAEvE"}
|
package/dist/auth/session.js
CHANGED
|
@@ -17,6 +17,16 @@ const mongoose_1 = __importDefault(require("mongoose"));
|
|
|
17
17
|
*/
|
|
18
18
|
exports.USER_SESSIONS_COLLECTION = 'user_sessions';
|
|
19
19
|
const OBJECT_ID = /^[a-f\d]{24}$/i;
|
|
20
|
+
/**
|
|
21
|
+
* Checks running right now, by session. Opening a thread sends several requests
|
|
22
|
+
* at once, each of which authenticates, and each would ask the database the same
|
|
23
|
+
* question across the internet. They share one answer instead.
|
|
24
|
+
*
|
|
25
|
+
* Only while the question is being asked: nothing is kept once it has been
|
|
26
|
+
* answered, so a session revoked a moment later is refused on the very next
|
|
27
|
+
* request, exactly as before.
|
|
28
|
+
*/
|
|
29
|
+
const inFlight = new Map();
|
|
20
30
|
/**
|
|
21
31
|
* Whether a verified session token still stands: for a token with a `sid`,
|
|
22
32
|
* its session belongs to the token's user and has neither been revoked nor
|
|
@@ -36,12 +46,21 @@ const checkSessionInDatabase = async (claims) => {
|
|
|
36
46
|
// Refuse rather than queue an authentication query while the database is down.
|
|
37
47
|
if (mongoose_1.default.connection.readyState !== 1)
|
|
38
48
|
return false;
|
|
39
|
-
const
|
|
49
|
+
const key = `${id}:${sid}`;
|
|
50
|
+
const running = inFlight.get(key);
|
|
51
|
+
if (running)
|
|
52
|
+
return running;
|
|
53
|
+
const lookup = mongoose_1.default.connection
|
|
54
|
+
.collection(exports.USER_SESSIONS_COLLECTION)
|
|
55
|
+
.findOne({
|
|
40
56
|
_id: new mongoose_1.default.Types.ObjectId(sid),
|
|
41
57
|
userId: new mongoose_1.default.Types.ObjectId(id),
|
|
42
58
|
expiresAt: { $gt: new Date() }
|
|
43
|
-
}, { projection: { _id: 1 }, readPreference: 'primary', maxTimeMS: 3000 })
|
|
44
|
-
|
|
59
|
+
}, { projection: { _id: 1 }, readPreference: 'primary', maxTimeMS: 3000 })
|
|
60
|
+
.then((session) => session !== null)
|
|
61
|
+
.finally(() => inFlight.delete(key));
|
|
62
|
+
inFlight.set(key, lookup);
|
|
63
|
+
return lookup;
|
|
45
64
|
};
|
|
46
65
|
let sessionCheck = checkSessionInDatabase;
|
|
47
66
|
const isCurrentSession = (claims) => sessionCheck(claims);
|
package/dist/auth/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":";;;;;;AAyEA,oEAEC;AA3ED,wDAAgC;AAEhC;;;;;;;;GAQG;AACU,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAExD,MAAM,SAAS,GAAG,gBAAgB,CAAC;AAInC;;;;;;;;GAQG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;AAErD;;;;;GAKG;AACH,MAAM,sBAAsB,GAAiB,KAAK,EAAE,MAAM,EAAE,EAAE;IAC5D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACxD,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAyC,CAAC;IAC9D,4EAA4E;IAC5E,uDAAuD;IACvD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAClE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,+EAA+E;IAC/E,IAAI,kBAAQ,CAAC,UAAU,CAAC,UAAU,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvD,MAAM,GAAG,GAAG,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,MAAM,MAAM,GAAG,kBAAQ,CAAC,UAAU;SAC/B,UAAU,CAAC,gCAAwB,CAAC;SACpC,OAAO,CACN;QACE,GAAG,EAAE,IAAI,kBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QACrC,MAAM,EAAE,IAAI,kBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvC,SAAS,EAAE,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE;KAC/B,EACD,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,CACvE;SACA,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;SACnC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,IAAI,YAAY,GAAiB,sBAAsB,CAAC;AAEjD,MAAM,gBAAgB,GAAG,CAAC,MAAe,EAAoB,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAA/E,QAAA,gBAAgB,oBAA+D;AAE5F;;;;GAIG;AACH,SAAgB,4BAA4B,CAAC,KAAoB;IAC/D,YAAY,GAAG,KAAK,IAAI,sBAAsB,CAAC;AACjD,CAAC"}
|
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
import { ConnectOptions } from 'mongoose';
|
|
2
|
+
/**
|
|
3
|
+
* How the pool behaves toward a database that is across the internet.
|
|
4
|
+
*
|
|
5
|
+
* Measured, not assumed: on the Pi a database lookup took about 17 ms on a warm
|
|
6
|
+
* connection and 850 to 1,370 ms on a cold one, so the distance to Atlas is not
|
|
7
|
+
* the cost. Opening a connection is. It is a TCP and TLS handshake and an
|
|
8
|
+
* authentication, from a small machine, and the driver defaults make a burst of
|
|
9
|
+
* requests pay for it badly:
|
|
10
|
+
*
|
|
11
|
+
* - It keeps no connections open, and an idle one is eventually dropped by
|
|
12
|
+
* something between here and Atlas, so the first request after a quiet spell
|
|
13
|
+
* starts from nothing.
|
|
14
|
+
* - It opens at most two connections at a time. Opening a thread sends five or
|
|
15
|
+
* six requests at once, so they queued behind each other, a second or so per
|
|
16
|
+
* pair, and the thread took three to seven seconds.
|
|
17
|
+
*
|
|
18
|
+
* So:
|
|
19
|
+
* - `minPoolSize` keeps enough connections open to cover that burst.
|
|
20
|
+
* - `maxConnecting` lets the pool open several at once when it does need more.
|
|
21
|
+
* - `maxIdleTimeMS` retires a connection that has sat idle for a few minutes,
|
|
22
|
+
* before something else kills it, and the pool opens a fresh one in its place.
|
|
23
|
+
* - `family: 4` skips the IPv6 half of every hostname lookup. Atlas is IPv4, and
|
|
24
|
+
* a resolver that is slow to answer for AAAA delays every new connection.
|
|
25
|
+
*
|
|
26
|
+
* Each can be set per deployment, for a database that is somewhere else.
|
|
27
|
+
*/
|
|
28
|
+
export declare function poolOptions(env?: NodeJS.ProcessEnv): ConnectOptions;
|
|
1
29
|
/**
|
|
2
30
|
* Connects once and throws on failure. There is deliberately no retry loop here.
|
|
3
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAWpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc,CAWhF;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,GAAU,cAAc,MAAM,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAchF,CAAC;AA4DF,eAAO,MAAM,YAAY,GAAU,cAAc,MAAM,KAAG,OAAO,CAAC,IAAI,CASrE,CAAC"}
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.disconnectDB = exports.connectDB = void 0;
|
|
7
|
+
exports.poolOptions = poolOptions;
|
|
7
8
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
9
|
const logger_1 = __importDefault(require("../logging/logger"));
|
|
9
10
|
let connected = false;
|
|
@@ -13,6 +14,42 @@ let connected = false;
|
|
|
13
14
|
*/
|
|
14
15
|
let pending = null;
|
|
15
16
|
let listenersRegistered = false;
|
|
17
|
+
/**
|
|
18
|
+
* How the pool behaves toward a database that is across the internet.
|
|
19
|
+
*
|
|
20
|
+
* Measured, not assumed: on the Pi a database lookup took about 17 ms on a warm
|
|
21
|
+
* connection and 850 to 1,370 ms on a cold one, so the distance to Atlas is not
|
|
22
|
+
* the cost. Opening a connection is. It is a TCP and TLS handshake and an
|
|
23
|
+
* authentication, from a small machine, and the driver defaults make a burst of
|
|
24
|
+
* requests pay for it badly:
|
|
25
|
+
*
|
|
26
|
+
* - It keeps no connections open, and an idle one is eventually dropped by
|
|
27
|
+
* something between here and Atlas, so the first request after a quiet spell
|
|
28
|
+
* starts from nothing.
|
|
29
|
+
* - It opens at most two connections at a time. Opening a thread sends five or
|
|
30
|
+
* six requests at once, so they queued behind each other, a second or so per
|
|
31
|
+
* pair, and the thread took three to seven seconds.
|
|
32
|
+
*
|
|
33
|
+
* So:
|
|
34
|
+
* - `minPoolSize` keeps enough connections open to cover that burst.
|
|
35
|
+
* - `maxConnecting` lets the pool open several at once when it does need more.
|
|
36
|
+
* - `maxIdleTimeMS` retires a connection that has sat idle for a few minutes,
|
|
37
|
+
* before something else kills it, and the pool opens a fresh one in its place.
|
|
38
|
+
* - `family: 4` skips the IPv6 half of every hostname lookup. Atlas is IPv4, and
|
|
39
|
+
* a resolver that is slow to answer for AAAA delays every new connection.
|
|
40
|
+
*
|
|
41
|
+
* Each can be set per deployment, for a database that is somewhere else.
|
|
42
|
+
*/
|
|
43
|
+
function poolOptions(env = process.env) {
|
|
44
|
+
const number = (value, fallback) => value !== undefined && value.trim() !== '' && Number.isFinite(Number(value)) ? Number(value) : fallback;
|
|
45
|
+
const family = number(env.MONGODB_IP_FAMILY, 4);
|
|
46
|
+
return {
|
|
47
|
+
minPoolSize: number(env.MONGODB_MIN_POOL_SIZE, 5),
|
|
48
|
+
maxConnecting: number(env.MONGODB_MAX_CONNECTING, 5),
|
|
49
|
+
maxIdleTimeMS: number(env.MONGODB_MAX_IDLE_MS, 180_000),
|
|
50
|
+
family: family === 6 ? 6 : family === 0 ? 0 : 4
|
|
51
|
+
};
|
|
52
|
+
}
|
|
16
53
|
/**
|
|
17
54
|
* Connects once and throws on failure. There is deliberately no retry loop here.
|
|
18
55
|
*
|
|
@@ -45,10 +82,11 @@ const connectDB = async (serviceName, uri) => {
|
|
|
45
82
|
exports.connectDB = connectDB;
|
|
46
83
|
async function connectOnce(mongoUri, serviceName) {
|
|
47
84
|
try {
|
|
48
|
-
await mongoose_1.default.connect(mongoUri);
|
|
85
|
+
await mongoose_1.default.connect(mongoUri, poolOptions());
|
|
49
86
|
connected = true;
|
|
50
87
|
registerConnectionListeners(serviceName);
|
|
51
88
|
logger_1.default.info('MongoDB connected', { service: serviceName });
|
|
89
|
+
await logRoundTrip(serviceName);
|
|
52
90
|
}
|
|
53
91
|
catch (error) {
|
|
54
92
|
logger_1.default.error('Failed to connect to MongoDB', {
|
|
@@ -58,6 +96,26 @@ async function connectOnce(mongoUri, serviceName) {
|
|
|
58
96
|
throw error;
|
|
59
97
|
}
|
|
60
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* How long one round trip to the database takes from here, once, at start.
|
|
101
|
+
*
|
|
102
|
+
* Every query is at least one of these, and a request makes several, so it is the
|
|
103
|
+
* number that explains whether a slow request was slow because of the database's
|
|
104
|
+
* distance or because of something else. Best effort: it never fails a start.
|
|
105
|
+
*/
|
|
106
|
+
async function logRoundTrip(serviceName) {
|
|
107
|
+
try {
|
|
108
|
+
const db = mongoose_1.default.connection.db;
|
|
109
|
+
if (!db)
|
|
110
|
+
return;
|
|
111
|
+
const started = performance.now();
|
|
112
|
+
await db.admin().ping();
|
|
113
|
+
logger_1.default.info('MongoDB round trip', { service: serviceName, ms: Math.round(performance.now() - started) });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// A start is not worth failing for a measurement.
|
|
117
|
+
}
|
|
118
|
+
}
|
|
61
119
|
/**
|
|
62
120
|
* Mongoose reconnects on its own once an initial connection has succeeded, so
|
|
63
121
|
* these only report state — but without them a drop is silent and the only
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/database/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export { requireInternalServiceToken, internalServiceTokenBypass, allowUserOrInt
|
|
|
25
25
|
export { createCorsMiddleware } from './middleware/corsMiddleware';
|
|
26
26
|
export { errorHandler } from './middleware/errorHandler';
|
|
27
27
|
export { requestLogger, requestLoggerWithMetrics, simpleRequestLogger } from './middleware/requestLogger';
|
|
28
|
+
export { recordTiming, slowRequestLogger } from './middleware/serverTiming';
|
|
28
29
|
export { securityHeaders, createRateLimiter, standardRateLimiter, strictRateLimiter } from './middleware/security';
|
|
29
30
|
export { validate } from './middleware/validate';
|
|
30
31
|
export type { UserPayload } from './types/auth';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC7K,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,eAAe,CAAC;AAG9B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,cAAc,OAAO,CAAC;AAGtB,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC7K,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,eAAe,CAAC;AAG9B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,cAAc,OAAO,CAAC;AAGtB,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,8 +18,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.
|
|
22
|
-
exports.extractSpanContext = exports.injectHeaders = exports.setSpanTag = exports.logToSpan = exports.createChildSpan = exports.tracingMiddleware = exports.startSpan = exports.getTracer = exports.initTracer = exports.register = exports.businessMetrics = exports.databaseQueriesTotal = exports.databaseQueryDuration = void 0;
|
|
21
|
+
exports.metricsMiddleware = exports.escapeRegex = exports.canAccessResource = exports.buildAccessQuery = exports.sendError = exports.sendSuccess = exports.createApiResponse = exports.correlationMiddleware = exports.generateCorrelationId = exports.validate = exports.strictRateLimiter = exports.standardRateLimiter = exports.createRateLimiter = exports.securityHeaders = exports.slowRequestLogger = exports.recordTiming = exports.simpleRequestLogger = exports.requestLoggerWithMetrics = exports.requestLogger = exports.errorHandler = exports.createCorsMiddleware = exports.SERVICE_ID_HEADER = exports.INTERNAL_TOKEN_HEADER = exports.verifyInternalToken = exports.allowUserOrInternalService = exports.internalServiceTokenBypass = exports.requireInternalServiceToken = exports.isCurrentSession = exports.USER_SESSIONS_COLLECTION = exports.requireAdmin = exports.optionalAuth = exports.authenticateToken = exports.PaymentRequiredError = exports.TooManyRequestsError = exports.ConflictError = exports.NotFoundError = exports.ForbiddenError = exports.UnauthorizedError = exports.BadRequestError = exports.HttpError = exports.requireEnv = exports.disconnectDB = exports.connectDB = exports.createHealthCheck = exports.metricsHandler = exports.healthLive = exports.healthCheck = exports.logger = exports.registerShutdown = exports.createBaseApp = void 0;
|
|
22
|
+
exports.extractSpanContext = exports.injectHeaders = exports.setSpanTag = exports.logToSpan = exports.createChildSpan = exports.tracingMiddleware = exports.startSpan = exports.getTracer = exports.initTracer = exports.register = exports.businessMetrics = exports.databaseQueriesTotal = exports.databaseQueryDuration = exports.httpRequestsTotal = exports.httpRequestDuration = void 0;
|
|
23
23
|
// App bootstrap
|
|
24
24
|
var createBaseApp_1 = require("./app/createBaseApp");
|
|
25
25
|
Object.defineProperty(exports, "createBaseApp", { enumerable: true, get: function () { return createBaseApp_1.createBaseApp; } });
|
|
@@ -91,6 +91,9 @@ var requestLogger_1 = require("./middleware/requestLogger");
|
|
|
91
91
|
Object.defineProperty(exports, "requestLogger", { enumerable: true, get: function () { return requestLogger_1.requestLogger; } });
|
|
92
92
|
Object.defineProperty(exports, "requestLoggerWithMetrics", { enumerable: true, get: function () { return requestLogger_1.requestLoggerWithMetrics; } });
|
|
93
93
|
Object.defineProperty(exports, "simpleRequestLogger", { enumerable: true, get: function () { return requestLogger_1.simpleRequestLogger; } });
|
|
94
|
+
var serverTiming_1 = require("./middleware/serverTiming");
|
|
95
|
+
Object.defineProperty(exports, "recordTiming", { enumerable: true, get: function () { return serverTiming_1.recordTiming; } });
|
|
96
|
+
Object.defineProperty(exports, "slowRequestLogger", { enumerable: true, get: function () { return serverTiming_1.slowRequestLogger; } });
|
|
94
97
|
var security_1 = require("./middleware/security");
|
|
95
98
|
Object.defineProperty(exports, "securityHeaders", { enumerable: true, get: function () { return security_1.securityHeaders; } });
|
|
96
99
|
Object.defineProperty(exports, "createRateLimiter", { enumerable: true, get: function () { return security_1.createRateLimiter; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS1D;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCtG;AACD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBlG"}
|
|
@@ -10,6 +10,7 @@ const env_1 = require("../config/env");
|
|
|
10
10
|
const tokens_1 = require("../oauth/tokens");
|
|
11
11
|
const session_1 = require("../auth/session");
|
|
12
12
|
const membership_1 = require("../groups/membership");
|
|
13
|
+
const serverTiming_1 = require("./serverTiming");
|
|
13
14
|
/**
|
|
14
15
|
* JWT authentication middleware
|
|
15
16
|
* Verifies JWT token and attaches user info (and its embedded groups) to
|
|
@@ -41,13 +42,19 @@ async function authenticateToken(req, res, next) {
|
|
|
41
42
|
}
|
|
42
43
|
// A signed-out or revoked device keeps a validly signed token; only its
|
|
43
44
|
// session record says it has ended.
|
|
44
|
-
|
|
45
|
+
const sessionStarted = performance.now();
|
|
46
|
+
const current = await (0, session_1.isCurrentSession)(claims);
|
|
47
|
+
(0, serverTiming_1.recordTiming)(res, 'session', performance.now() - sessionStarted);
|
|
48
|
+
if (!current) {
|
|
45
49
|
res.status(401).json({ success: false, message: 'Session has ended' });
|
|
46
50
|
return;
|
|
47
51
|
}
|
|
48
52
|
// Membership is asked of group-service, not read from the token, so a
|
|
49
|
-
// change applies within seconds rather than at the next renewal.
|
|
53
|
+
// change applies within seconds rather than at the next renewal. Timed on
|
|
54
|
+
// its own: it is the one step that can wait on another service.
|
|
55
|
+
const groupsStarted = performance.now();
|
|
50
56
|
const groups = await (0, membership_1.currentGroupsOf)(claims);
|
|
57
|
+
(0, serverTiming_1.recordTiming)(res, 'groups', performance.now() - groupsStarted);
|
|
51
58
|
req.user = { ...claims, groups };
|
|
52
59
|
req.userGroups = groups;
|
|
53
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/middleware/authMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corsMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"corsMiddleware.d.ts","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI9C,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAsCxF"}
|
|
@@ -35,6 +35,11 @@ function createCorsMiddleware(options = {}) {
|
|
|
35
35
|
// network tab and no failing request to point at.
|
|
36
36
|
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
37
37
|
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-correlation-id', 'x-session-id'],
|
|
38
|
+
// How long a browser may keep the answer to a preflight. Without it Chrome
|
|
39
|
+
// keeps it for five seconds, so nearly every POST, PUT and DELETE (a read
|
|
40
|
+
// marker, a typing notice, a send) was preceded by an extra OPTIONS round
|
|
41
|
+
// trip through Cloudflare and the tunnel. Chrome caps this at two hours.
|
|
42
|
+
maxAge: 7200,
|
|
38
43
|
exposedHeaders: options.exposedHeaders
|
|
39
44
|
});
|
|
40
45
|
if (bypassPaths.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corsMiddleware.js","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":";;;;;AAkCA,
|
|
1
|
+
{"version":3,"file":"corsMiddleware.js","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":";;;;;AAkCA,oDAsCC;AAxED,gDAAwB;AAExB,+DAAuC;AACvC,mDAAqD;AA0BrD;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,UAAiC,EAAE;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IAE9C,MAAM,WAAW,GAAG,IAAA,cAAI,EAAC;QACvB,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC3B,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;iBACtE,KAAK,CAAC,GAAG,CAAC;iBACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBAClB,MAAM,CAAC,OAAO,CAAC,CAAC;YACnB,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/C,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC9B,CAAC;YACD,gBAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/C,qEAAqE;YACrE,sDAAsD;YACtD,OAAO,QAAQ,CAAC,IAAI,0BAAc,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,WAAW,EAAE,IAAI;QACjB,uEAAuE;QACvE,uEAAuE;QACvE,wEAAwE;QACxE,kDAAkD;QAClD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC7D,cAAc,EAAE,CAAC,cAAc,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,cAAc,CAAC;QACzG,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,MAAM,EAAE,IAAI;QACZ,cAAc,EAAE,OAAO,CAAC,cAAc;KACvC,CAAC,CAAC;IAEH,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAA6B,CAAC;IAEnE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QAC7E,OAAQ,WAA8B,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RequestHandler, Response } from 'express';
|
|
2
|
+
/** Notes how long a named phase took, and publishes all the phases so far as `Server-Timing`. */
|
|
3
|
+
export declare function recordTiming(res: Response, name: string, ms: number): void;
|
|
4
|
+
/**
|
|
5
|
+
* Logs a warning for every request that took `thresholdMs` or longer, with the
|
|
6
|
+
* phases recorded along the way. A long-lived stream is not slow, it is a stream.
|
|
7
|
+
*/
|
|
8
|
+
export declare function slowRequestLogger(thresholdMs?: number): RequestHandler;
|
|
9
|
+
//# sourceMappingURL=serverTiming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverTiming.d.ts","sourceRoot":"","sources":["../../src/middleware/serverTiming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAwB/E,iGAAiG;AACjG,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAY1E;AAKD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,SAAO,GAAG,cAAc,CAiBpE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.recordTiming = recordTiming;
|
|
7
|
+
exports.slowRequestLogger = slowRequestLogger;
|
|
8
|
+
const logger_1 = __importDefault(require("../logging/logger"));
|
|
9
|
+
const timingsOf = (res) => {
|
|
10
|
+
const locals = (res.locals ??= {});
|
|
11
|
+
return (locals.timings ??= {});
|
|
12
|
+
};
|
|
13
|
+
/** Notes how long a named phase took, and publishes all the phases so far as `Server-Timing`. */
|
|
14
|
+
function recordTiming(res, name, ms) {
|
|
15
|
+
const timings = timingsOf(res);
|
|
16
|
+
timings[name] = Math.round(ms * 10) / 10;
|
|
17
|
+
// Headers are final once the body has started, so a late note is only logged.
|
|
18
|
+
if (typeof res.setHeader !== 'function' || res.headersSent)
|
|
19
|
+
return;
|
|
20
|
+
res.setHeader('Server-Timing', Object.entries(timings)
|
|
21
|
+
.map(([phase, dur]) => `${phase};dur=${dur}`)
|
|
22
|
+
.join(', '));
|
|
23
|
+
}
|
|
24
|
+
/** Ids are removed from a path, so slow requests group by route instead of by record. */
|
|
25
|
+
const routeOf = (url) => url.split('?')[0].replace(/[a-f0-9]{24}/gi, ':id');
|
|
26
|
+
/**
|
|
27
|
+
* Logs a warning for every request that took `thresholdMs` or longer, with the
|
|
28
|
+
* phases recorded along the way. A long-lived stream is not slow, it is a stream.
|
|
29
|
+
*/
|
|
30
|
+
function slowRequestLogger(thresholdMs = 1000) {
|
|
31
|
+
return (req, res, next) => {
|
|
32
|
+
const started = performance.now();
|
|
33
|
+
res.on('finish', () => {
|
|
34
|
+
const ms = performance.now() - started;
|
|
35
|
+
if (ms < thresholdMs)
|
|
36
|
+
return;
|
|
37
|
+
if (String(res.getHeader('Content-Type') ?? '').includes('text/event-stream'))
|
|
38
|
+
return;
|
|
39
|
+
logger_1.default.warn('Slow request', {
|
|
40
|
+
method: req.method,
|
|
41
|
+
route: routeOf(req.originalUrl ?? req.url),
|
|
42
|
+
status: res.statusCode,
|
|
43
|
+
ms: Math.round(ms),
|
|
44
|
+
timings: timingsOf(res)
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
next();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=serverTiming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverTiming.js","sourceRoot":"","sources":["../../src/middleware/serverTiming.ts"],"names":[],"mappings":";;;;;AAyBA,oCAYC;AASD,8CAiBC;AA9DD,+DAAuC;AAkBvC,MAAM,SAAS,GAAG,CAAC,GAAa,EAAW,EAAE;IAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,EAAE,CAA0B,CAAC;IAC5D,OAAO,CAAC,MAAM,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,iGAAiG;AACjG,SAAgB,YAAY,CAAC,GAAa,EAAE,IAAY,EAAE,EAAU;IAClE,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAEzC,8EAA8E;IAC9E,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,UAAU,IAAI,GAAG,CAAC,WAAW;QAAE,OAAO;IACnE,GAAG,CAAC,SAAS,CACX,eAAe,EACf,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACpB,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,GAAG,EAAE,CAAC;SAC5C,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AAE7F;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,WAAW,GAAG,IAAI;IAClD,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpB,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;YACvC,IAAI,EAAE,GAAG,WAAW;gBAAE,OAAO;YAC7B,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;gBAAE,OAAO;YACtF,gBAAM,CAAC,IAAI,CAAC,cAAc,EAAE;gBAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,GAAG,CAAC;gBAC1C,MAAM,EAAE,GAAG,CAAC,UAAU;gBACtB,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClB,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC;aACxB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,UAAU,EACV,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,UAAU,EACV,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAiB1D,eAAO,MAAM,UAAU,GAAI,aAAa,MAAM,KAAG,MAchD,CAAC;AAKF,eAAO,MAAM,SAAS,QAAO,MAK5B,CAAC;AAGF,eAAO,MAAM,SAAS,GAAI,eAAe,MAAM,EAAE,SAAS,IAAI,GAAG,OAAO,SASvE,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,SAmBhF,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,eAAe,MAAM,EAAE,QAAQ,IAAI,GAAG,OAAO,SAE5E,CAAC;AAGF,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,EAAE,OAAO,MAAM,EAAE,OAAO,UAAU,SAErE,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,EAAE,KAAK,MAAM,EAAE,OAAO,cAAc,SAExE,CAAC;AAGF,eAAO,MAAM,aAAa,GAAI,MAAM,IAAI;;CAIvC,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,KACrD,OAEF,CAAC"}
|
package/dist/tracing/index.js
CHANGED
|
@@ -7,18 +7,25 @@ const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-h
|
|
|
7
7
|
const resources_1 = require("@opentelemetry/resources");
|
|
8
8
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
9
9
|
// Initialize OpenTelemetry tracer provider, exporting via OTLP/HTTP.
|
|
10
|
-
// Endpoint resolution: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT > JAEGER_ENDPOINT
|
|
10
|
+
// Endpoint resolution: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT > JAEGER_ENDPOINT.
|
|
11
|
+
//
|
|
12
|
+
// With neither set there is no exporter at all. This used to fall back to an
|
|
13
|
+
// in-cluster `jaeger-collector` host, which is only a good default where one is
|
|
14
|
+
// running. Where it is not, every service tried to send its spans to a name that
|
|
15
|
+
// does not exist every few seconds, resolving it again each time. A failed
|
|
16
|
+
// lookup holds one of Node's few shared worker threads (the same ones that
|
|
17
|
+
// resolve every other hostname the service calls) until the resolver gives up.
|
|
18
|
+
// Spans are still created and passed along in a trace context; they simply have
|
|
19
|
+
// nowhere to be sent until an endpoint is named.
|
|
11
20
|
const initTracer = (serviceName) => {
|
|
12
|
-
const url = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
|
|
13
|
-
process.env.JAEGER_ENDPOINT ||
|
|
14
|
-
'http://jaeger-collector:4318/v1/traces';
|
|
21
|
+
const url = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.JAEGER_ENDPOINT;
|
|
15
22
|
const provider = new sdk_trace_node_1.NodeTracerProvider({
|
|
16
23
|
resource: (0, resources_1.resourceFromAttributes)({
|
|
17
24
|
[semantic_conventions_1.ATTR_SERVICE_NAME]: serviceName,
|
|
18
25
|
[semantic_conventions_1.ATTR_SERVICE_VERSION]: process.env.npm_package_version || '1.0.0',
|
|
19
26
|
'deployment.environment': process.env.NODE_ENV || 'development',
|
|
20
27
|
}),
|
|
21
|
-
spanProcessors: [new sdk_trace_node_1.BatchSpanProcessor(new exporter_trace_otlp_http_1.OTLPTraceExporter({ url }))],
|
|
28
|
+
spanProcessors: url ? [new sdk_trace_node_1.BatchSpanProcessor(new exporter_trace_otlp_http_1.OTLPTraceExporter({ url }))] : [],
|
|
22
29
|
});
|
|
23
30
|
provider.register();
|
|
24
31
|
return provider.getTracer(serviceName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tracing/index.ts"],"names":[],"mappings":";;;AAAA,4CAU4B;AAE5B,kEAAuF;AACvF,sFAA4E;AAC5E,wDAAkE;AAClE,8EAA8F;AAE9F,qEAAqE;AACrE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tracing/index.ts"],"names":[],"mappings":";;;AAAA,4CAU4B;AAE5B,kEAAuF;AACvF,sFAA4E;AAC5E,wDAAkE;AAClE,8EAA8F;AAE9F,qEAAqE;AACrE,6EAA6E;AAC7E,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,iFAAiF;AACjF,2EAA2E;AAC3E,2EAA2E;AAC3E,+EAA+E;AAC/E,gFAAgF;AAChF,iDAAiD;AAC1C,MAAM,UAAU,GAAG,CAAC,WAAmB,EAAU,EAAE;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAE1F,MAAM,QAAQ,GAAG,IAAI,mCAAkB,CAAC;QACtC,QAAQ,EAAE,IAAA,kCAAsB,EAAC;YAC/B,CAAC,wCAAiB,CAAC,EAAE,WAAW;YAChC,CAAC,2CAAoB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO;YAClE,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;SAChE,CAAC;QACF,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,mCAAkB,CAAC,IAAI,4CAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;KACpF,CAAC,CAAC;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAEpB,OAAO,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACzC,CAAC,CAAC;AAdW,QAAA,UAAU,cAcrB;AAEF,yBAAyB;AACzB,IAAI,MAAM,GAAkB,IAAI,CAAC;AAE1B,MAAM,SAAS,GAAG,GAAW,EAAE;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAA,kBAAU,EAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,iBAAiB,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB;AAEF,wFAAwF;AACjF,MAAM,SAAS,GAAG,CAAC,aAAqB,EAAE,MAAuB,EAAE,EAAE;IAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAA,iBAAS,GAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IACD,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,aAAa,GACjB,aAAa,IAAI,MAAM,CAAC,CAAC,CAAC,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7E,OAAO,IAAA,iBAAS,GAAE,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AACxE,CAAC,CAAC;AATW,QAAA,SAAS,aASpB;AAEF,sDAAsD;AAC/C,MAAM,iBAAiB,GAAG,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACnF,MAAM,aAAa,GAAG,iBAAW,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,IAAA,iBAAS,GAAE,CAAC,SAAS,CAChC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,EAC3B,EAAE,IAAI,EAAE,cAAQ,CAAC,MAAM,EAAE,EACzB,aAAa,CACd,CAAC;IACF,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAEvC,0CAA0C;IAC1C,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAEhB,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,GAAG,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAnBW,QAAA,iBAAiB,qBAmB5B;AAEF,+BAA+B;AACxB,MAAM,eAAe,GAAG,CAAC,aAAqB,EAAE,MAAsB,EAAE,EAAE;IAC/E,OAAO,IAAA,iBAAS,EAAC,aAAa,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC,CAAC;AAFW,QAAA,eAAe,mBAE1B;AAEF,gCAAgC;AACzB,MAAM,SAAS,GAAG,CAAC,IAAU,EAAE,KAAa,EAAE,IAAiB,EAAE,EAAE;IACxE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC;AAFW,QAAA,SAAS,aAEpB;AAEF,8BAA8B;AACvB,MAAM,UAAU,GAAG,CAAC,IAAU,EAAE,GAAW,EAAE,KAAqB,EAAE,EAAE;IAC3E,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC,CAAC;AAFW,QAAA,UAAU,cAErB;AAEF,0EAA0E;AACnE,MAAM,aAAa,GAAG,CAAC,IAAU,EAAE,EAAE;IAC1C,MAAM,OAAO,GAA8B,EAAE,CAAC;IAC9C,iBAAW,CAAC,MAAM,CAAC,WAAK,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IACnE,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAJW,QAAA,aAAa,iBAIxB;AAEF,+FAA+F;AACxF,MAAM,kBAAkB,GAAG,CAChC,OAAsD,EAC7C,EAAE;IACX,OAAO,iBAAW,CAAC,OAAO,CAAC,aAAO,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;AACxD,CAAC,CAAC;AAJW,QAAA,kBAAkB,sBAI7B"}
|