@tumbaland/backend-core 1.45.0 → 1.46.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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Server-to-server calls to file-service's `/internal` API, authenticated with
3
+ * `FILE_SERVICE_API_KEY`. Browsers never come through here: they get a signed
4
+ * URL from this client and upload or download against file-service directly.
5
+ *
6
+ * This is the protocol only. What a failure means is the caller's decision (a
7
+ * thread that renders without its images beats one that fails to load), so
8
+ * every call throws a `FileServiceError` and leaves degrading to the caller.
9
+ */
10
+ export declare class FileServiceError extends Error {
11
+ readonly status: number;
12
+ constructor(status: number, message: string);
13
+ }
14
+ export interface DownloadUrl {
15
+ downloadUrl: string;
16
+ /** When the URL stops working, in epoch milliseconds. */
17
+ expiresMs: number;
18
+ expiresInMinutes: number;
19
+ }
20
+ /**
21
+ * A signed PUT URL the browser uploads to directly.
22
+ *
23
+ * `maxBytes` is signed into the URL and file-service refuses a bigger body, so
24
+ * the size a storage quota was checked against is an upper bound on what lands.
25
+ */
26
+ export declare function getUploadUrl(fileId: string, options?: {
27
+ mimetype?: string;
28
+ expiresInMinutes?: number;
29
+ maxBytes?: number;
30
+ }): Promise<string>;
31
+ /** A signed GET URL for one file. */
32
+ export declare function getDownloadUrl(fileId: string, expiresInMinutes?: number): Promise<DownloadUrl>;
33
+ /**
34
+ * Signed GET URLs for many files, keyed by fileId, in one request per thousand.
35
+ *
36
+ * Signing is pure HMAC and file-service snaps the expiry to a bucket, so the
37
+ * same file yields a byte-identical URL for a while. That is what lets the
38
+ * browser's cache work; a per-file request for each one tripped the rate
39
+ * limiter on a 100-photo collage.
40
+ */
41
+ export declare function getDownloadUrls(fileIds: string[], expiresInMinutes?: number): Promise<Record<string, DownloadUrl>>;
42
+ /** Stores bytes this service produced itself, such as a thumbnail. */
43
+ export declare function putFile(fileId: string, bytes: Buffer, mimetype: string): Promise<void>;
44
+ /** Reads a stored file back. A missing file is a `FileServiceError` with status 404. */
45
+ export declare function getFile(fileId: string): Promise<Buffer>;
46
+ export declare function deleteFile(fileId: string): Promise<void>;
47
+ /** Deletes every file whose id starts with `prefix`. */
48
+ export declare function deleteFolder(prefix: string): Promise<void>;
49
+ /**
50
+ * How many bytes a stored file really takes, or null when there is no such
51
+ * file (an upload that never finished).
52
+ */
53
+ export declare function storedSize(fileId: string): Promise<number | null>;
54
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/fileService/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EAC9B,OAAO,EAAE,MAAM;CAKlB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AA0CD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAChF,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,qCAAqC;AACrC,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,SAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,gBAAgB,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAWpH;AAED,sEAAsE;AACtE,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5F;AAED,wFAAwF;AACxF,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG7D;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wDAAwD;AACxD,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOvE"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * Server-to-server calls to file-service's `/internal` API, authenticated with
4
+ * `FILE_SERVICE_API_KEY`. Browsers never come through here: they get a signed
5
+ * URL from this client and upload or download against file-service directly.
6
+ *
7
+ * This is the protocol only. What a failure means is the caller's decision (a
8
+ * thread that renders without its images beats one that fails to load), so
9
+ * every call throws a `FileServiceError` and leaves degrading to the caller.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FileServiceError = void 0;
13
+ exports.getUploadUrl = getUploadUrl;
14
+ exports.getDownloadUrl = getDownloadUrl;
15
+ exports.getDownloadUrls = getDownloadUrls;
16
+ exports.putFile = putFile;
17
+ exports.getFile = getFile;
18
+ exports.deleteFile = deleteFile;
19
+ exports.deleteFolder = deleteFolder;
20
+ exports.storedSize = storedSize;
21
+ /** Abort a call that gets no response, so callers degrade instead of hanging. */
22
+ const REQUEST_TIMEOUT_MS = 10_000;
23
+ /** The most fileIds file-service signs in one `/internal/download-urls` request. */
24
+ const DOWNLOAD_URLS_PER_REQUEST = 1000;
25
+ class FileServiceError extends Error {
26
+ status;
27
+ constructor(status, message) {
28
+ super(message);
29
+ this.status = status;
30
+ this.name = 'FileServiceError';
31
+ }
32
+ }
33
+ exports.FileServiceError = FileServiceError;
34
+ const baseUrl = () => (process.env.FILE_SERVICE_URL || 'http://localhost:5002').replace(/\/$/, '');
35
+ const apiKey = () => {
36
+ const key = process.env.FILE_SERVICE_API_KEY;
37
+ if (!key)
38
+ throw new Error('FILE_SERVICE_API_KEY env var is required');
39
+ return key;
40
+ };
41
+ async function send(method, path, body) {
42
+ const headers = { 'X-Internal-Api-Key': apiKey() };
43
+ let payload;
44
+ if (body && 'json' in body) {
45
+ headers['Content-Type'] = 'application/json';
46
+ payload = JSON.stringify(body.json);
47
+ }
48
+ else if (body) {
49
+ headers['Content-Type'] = body.mimetype;
50
+ payload = new Uint8Array(body.bytes);
51
+ }
52
+ const response = await fetch(`${baseUrl()}${path}`, {
53
+ method,
54
+ headers,
55
+ body: payload,
56
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
57
+ });
58
+ if (!response.ok) {
59
+ throw new FileServiceError(response.status, `file-service ${method} ${path} -> ${response.status}`);
60
+ }
61
+ return response;
62
+ }
63
+ async function data(method, path, json) {
64
+ const response = await send(method, path, json === undefined ? undefined : { json });
65
+ return (await response.json()).data;
66
+ }
67
+ /**
68
+ * A signed PUT URL the browser uploads to directly.
69
+ *
70
+ * `maxBytes` is signed into the URL and file-service refuses a bigger body, so
71
+ * the size a storage quota was checked against is an upper bound on what lands.
72
+ */
73
+ async function getUploadUrl(fileId, options = {}) {
74
+ const { mimetype, expiresInMinutes = 15, maxBytes } = options;
75
+ const result = await data('POST', '/internal/upload-url', {
76
+ fileId,
77
+ expiresInMinutes,
78
+ ...(mimetype === undefined ? {} : { mimetype }),
79
+ ...(maxBytes === undefined ? {} : { maxBytes })
80
+ });
81
+ return result.uploadUrl;
82
+ }
83
+ /** A signed GET URL for one file. */
84
+ async function getDownloadUrl(fileId, expiresInMinutes = 60) {
85
+ return data('POST', '/internal/download-url', { fileId, expiresInMinutes });
86
+ }
87
+ /**
88
+ * Signed GET URLs for many files, keyed by fileId, in one request per thousand.
89
+ *
90
+ * Signing is pure HMAC and file-service snaps the expiry to a bucket, so the
91
+ * same file yields a byte-identical URL for a while. That is what lets the
92
+ * browser's cache work; a per-file request for each one tripped the rate
93
+ * limiter on a 100-photo collage.
94
+ */
95
+ async function getDownloadUrls(fileIds, expiresInMinutes = 60) {
96
+ const unique = [...new Set(fileIds.filter(Boolean))];
97
+ const urls = {};
98
+ for (let i = 0; i < unique.length; i += DOWNLOAD_URLS_PER_REQUEST) {
99
+ const result = await data('POST', '/internal/download-urls', {
100
+ fileIds: unique.slice(i, i + DOWNLOAD_URLS_PER_REQUEST),
101
+ expiresInMinutes
102
+ });
103
+ Object.assign(urls, result.urls);
104
+ }
105
+ return urls;
106
+ }
107
+ /** Stores bytes this service produced itself, such as a thumbnail. */
108
+ async function putFile(fileId, bytes, mimetype) {
109
+ await send('PUT', `/internal/files/${fileId}`, { bytes, mimetype });
110
+ }
111
+ /** Reads a stored file back. A missing file is a `FileServiceError` with status 404. */
112
+ async function getFile(fileId) {
113
+ const response = await send('GET', `/internal/files/${fileId}`);
114
+ return Buffer.from(await response.arrayBuffer());
115
+ }
116
+ async function deleteFile(fileId) {
117
+ await send('DELETE', `/internal/files/${fileId}`);
118
+ }
119
+ /** Deletes every file whose id starts with `prefix`. */
120
+ async function deleteFolder(prefix) {
121
+ await send('DELETE', '/internal/files/folder', { json: { prefix } });
122
+ }
123
+ /**
124
+ * How many bytes a stored file really takes, or null when there is no such
125
+ * file (an upload that never finished).
126
+ */
127
+ async function storedSize(fileId) {
128
+ try {
129
+ return (await data('GET', `/internal/meta/${fileId}`)).size;
130
+ }
131
+ catch (error) {
132
+ if (error instanceof FileServiceError && error.status === 404)
133
+ return null;
134
+ throw error;
135
+ }
136
+ }
137
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/fileService/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * as fileService from './client';
2
+ export { FileServiceError } from './client';
3
+ export type { DownloadUrl } from './client';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fileService/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.FileServiceError = exports.fileService = void 0;
37
+ exports.fileService = __importStar(require("./client"));
38
+ var client_1 = require("./client");
39
+ Object.defineProperty(exports, "FileServiceError", { enumerable: true, get: function () { return client_1.FileServiceError; } });
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fileService/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wDAAwC;AACxC,mCAA4C;AAAnC,0GAAA,gBAAgB,OAAA"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export type { PaymentRequiredDetails } from './errors/HttpError';
13
13
  export * from './entitlements';
14
14
  export * from './groups';
15
15
  export * from './apiKeys';
16
+ export * from './fileService';
16
17
  export * from './oauth';
17
18
  export * from './audit';
18
19
  export { authenticateToken, optionalAuth } from './middleware/authMiddleware';
@@ -28,6 +29,7 @@ export { generateCorrelationId, correlationMiddleware } from './utils/correlatio
28
29
  export { createApiResponse, sendSuccess, sendError } from './utils/response';
29
30
  export type { ApiResponse } from './utils/response';
30
31
  export { buildAccessQuery, canAccessResource } from './utils/permissionUtils';
32
+ export { escapeRegex } from './utils/escapeRegex';
31
33
  export { metricsMiddleware, httpRequestDuration, httpRequestsTotal, databaseQueryDuration, databaseQueriesTotal, businessMetrics, register } from './metrics';
32
34
  export { initTracer, getTracer, startSpan, tracingMiddleware, createChildSpan, logToSpan, setSpanTag, injectHeaders, extractSpanContext } from './tracing';
33
35
  //# sourceMappingURL=index.d.ts.map
@@ -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,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACtG,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;AAG9E,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,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACtG,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"}
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.databaseQueryDuration = exports.httpRequestsTotal = exports.httpRequestDuration = exports.metricsMiddleware = 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.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.isLegacySessionlessToken = exports.isCurrentSession = exports.USER_SESSIONS_COLLECTION = 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 = void 0;
21
+ exports.httpRequestsTotal = exports.httpRequestDuration = 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.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.isLegacySessionlessToken = exports.isCurrentSession = exports.USER_SESSIONS_COLLECTION = 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 = 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; } });
@@ -58,6 +58,8 @@ __exportStar(require("./entitlements"), exports);
58
58
  __exportStar(require("./groups"), exports);
59
59
  // API keys (non-browser clients: MCP servers, scripts, agents)
60
60
  __exportStar(require("./apiKeys"), exports);
61
+ // file-service's internal API (signed URLs, server-side file reads and writes)
62
+ __exportStar(require("./fileService"), exports);
61
63
  // OAuth 2.1 authorization server, for assistants connecting over MCP
62
64
  __exportStar(require("./oauth"), exports);
63
65
  __exportStar(require("./audit"), exports);
@@ -102,6 +104,8 @@ Object.defineProperty(exports, "sendError", { enumerable: true, get: function ()
102
104
  var permissionUtils_1 = require("./utils/permissionUtils");
103
105
  Object.defineProperty(exports, "buildAccessQuery", { enumerable: true, get: function () { return permissionUtils_1.buildAccessQuery; } });
104
106
  Object.defineProperty(exports, "canAccessResource", { enumerable: true, get: function () { return permissionUtils_1.canAccessResource; } });
107
+ var escapeRegex_1 = require("./utils/escapeRegex");
108
+ Object.defineProperty(exports, "escapeRegex", { enumerable: true, get: function () { return escapeRegex_1.escapeRegex; } });
105
109
  // Metrics
106
110
  var metrics_1 = require("./metrics");
107
111
  Object.defineProperty(exports, "metricsMiddleware", { enumerable: true, get: function () { return metrics_1.metricsMiddleware; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;;;;;;;;;;;;;;;;;;;AAErF,gBAAgB;AAChB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,2CAAkD;AAAzC,4GAAA,gBAAgB,OAAA;AAGzB,UAAU;AACV,2CAAqD;AAA5C,iHAAA,OAAO,OAAU;AAE1B,gBAAgB;AAChB,8DAAoF;AAA3E,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,kHAAA,cAAc,OAAA;AAChD,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAG1B,WAAW;AACX,oDAAgE;AAAvD,uGAAA,SAAS,OAAA;AAAE,0GAAA,YAAY,OAAA;AAEhC,SAAS;AACT,oCAA0C;AAAjC,iGAAA,UAAU,OAAA;AAEnB,SAAS;AACT,gDAA6K;AAApK,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAGhJ,wDAAwD;AACxD,iDAA+B;AAE/B,0DAA0D;AAC1D,2CAAyB;AAEzB,+DAA+D;AAC/D,4CAA0B;AAE1B,qEAAqE;AACrE,0CAAwB;AACxB,0CAAwB;AAExB,aAAa;AACb,8DAA8E;AAArE,mHAAA,iBAAiB,OAAA;AAAE,8GAAA,YAAY,OAAA;AACxC,0CAAsG;AAA7F,mHAAA,wBAAwB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,mHAAA,wBAAwB,OAAA;AAC7E,wEAO0C;AANxC,kIAAA,2BAA2B,OAAA;AAC3B,iIAAA,0BAA0B,OAAA;AAC1B,iIAAA,0BAA0B,OAAA;AAC1B,0HAAA,mBAAmB,OAAA;AACnB,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AAEnB,8DAAmE;AAA1D,sHAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,4GAAA,YAAY,OAAA;AACrB,4DAA0G;AAAjG,8GAAA,aAAa,OAAA;AAAE,yHAAA,wBAAwB,OAAA;AAAE,oHAAA,mBAAmB,OAAA;AACrE,kDAAmH;AAA1G,2GAAA,eAAe,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AAAE,+GAAA,mBAAmB,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AACnF,kDAAiD;AAAxC,oGAAA,QAAQ,OAAA;AAKjB,QAAQ;AACR,mDAAmF;AAA1E,oHAAA,qBAAqB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AACrD,6CAA6E;AAApE,6GAAA,iBAAiB,OAAA;AAAE,uGAAA,WAAW,OAAA;AAAE,qGAAA,SAAS,OAAA;AAElD,2DAA8E;AAArE,mHAAA,gBAAgB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAE5C,UAAU;AACV,qCAQmB;AAPjB,4GAAA,iBAAiB,OAAA;AACjB,8GAAA,mBAAmB,OAAA;AACnB,4GAAA,iBAAiB,OAAA;AACjB,gHAAA,qBAAqB,OAAA;AACrB,+GAAA,oBAAoB,OAAA;AACpB,0GAAA,eAAe,OAAA;AACf,mGAAA,QAAQ,OAAA;AAGV,UAAU;AACV,qCAUmB;AATjB,qGAAA,UAAU,OAAA;AACV,oGAAA,SAAS,OAAA;AACT,oGAAA,SAAS,OAAA;AACT,4GAAA,iBAAiB,OAAA;AACjB,0GAAA,eAAe,OAAA;AACf,oGAAA,SAAS,OAAA;AACT,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AACb,6GAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;;;;;;;;;;;;;;;;;;;AAErF,gBAAgB;AAChB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,2CAAkD;AAAzC,4GAAA,gBAAgB,OAAA;AAGzB,UAAU;AACV,2CAAqD;AAA5C,iHAAA,OAAO,OAAU;AAE1B,gBAAgB;AAChB,8DAAoF;AAA3E,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,kHAAA,cAAc,OAAA;AAChD,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAG1B,WAAW;AACX,oDAAgE;AAAvD,uGAAA,SAAS,OAAA;AAAE,0GAAA,YAAY,OAAA;AAEhC,SAAS;AACT,oCAA0C;AAAjC,iGAAA,UAAU,OAAA;AAEnB,SAAS;AACT,gDAA6K;AAApK,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAGhJ,wDAAwD;AACxD,iDAA+B;AAE/B,0DAA0D;AAC1D,2CAAyB;AAEzB,+DAA+D;AAC/D,4CAA0B;AAE1B,+EAA+E;AAC/E,gDAA8B;AAE9B,qEAAqE;AACrE,0CAAwB;AACxB,0CAAwB;AAExB,aAAa;AACb,8DAA8E;AAArE,mHAAA,iBAAiB,OAAA;AAAE,8GAAA,YAAY,OAAA;AACxC,0CAAsG;AAA7F,mHAAA,wBAAwB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,mHAAA,wBAAwB,OAAA;AAC7E,wEAO0C;AANxC,kIAAA,2BAA2B,OAAA;AAC3B,iIAAA,0BAA0B,OAAA;AAC1B,iIAAA,0BAA0B,OAAA;AAC1B,0HAAA,mBAAmB,OAAA;AACnB,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AAEnB,8DAAmE;AAA1D,sHAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,4GAAA,YAAY,OAAA;AACrB,4DAA0G;AAAjG,8GAAA,aAAa,OAAA;AAAE,yHAAA,wBAAwB,OAAA;AAAE,oHAAA,mBAAmB,OAAA;AACrE,kDAAmH;AAA1G,2GAAA,eAAe,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AAAE,+GAAA,mBAAmB,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AACnF,kDAAiD;AAAxC,oGAAA,QAAQ,OAAA;AAKjB,QAAQ;AACR,mDAAmF;AAA1E,oHAAA,qBAAqB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AACrD,6CAA6E;AAApE,6GAAA,iBAAiB,OAAA;AAAE,uGAAA,WAAW,OAAA;AAAE,qGAAA,SAAS,OAAA;AAElD,2DAA8E;AAArE,mHAAA,gBAAgB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAC5C,mDAAkD;AAAzC,0GAAA,WAAW,OAAA;AAEpB,UAAU;AACV,qCAQmB;AAPjB,4GAAA,iBAAiB,OAAA;AACjB,8GAAA,mBAAmB,OAAA;AACnB,4GAAA,iBAAiB,OAAA;AACjB,gHAAA,qBAAqB,OAAA;AACrB,+GAAA,oBAAoB,OAAA;AACpB,0GAAA,eAAe,OAAA;AACf,mGAAA,QAAQ,OAAA;AAGV,UAAU;AACV,qCAUmB;AATjB,qGAAA,UAAU,OAAA;AACV,oGAAA,SAAS,OAAA;AACT,oGAAA,SAAS,OAAA;AACT,4GAAA,iBAAiB,OAAA;AACjB,0GAAA,eAAe,OAAA;AACf,oGAAA,SAAS,OAAA;AACT,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AACb,6GAAA,kBAAkB,OAAA"}
@@ -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;AAG9C,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,CA+BxF"}
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,CAiCxF"}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createCorsMiddleware = createCorsMiddleware;
7
7
  const cors_1 = __importDefault(require("cors"));
8
8
  const logger_1 = __importDefault(require("../logging/logger"));
9
+ const HttpError_1 = require("../errors/HttpError");
9
10
  /**
10
11
  * Shared CORS middleware with an explicit origin whitelist.
11
12
  * Requests without an Origin header (server-to-server, curl, health checks)
@@ -23,7 +24,9 @@ function createCorsMiddleware(options = {}) {
23
24
  return callback(null, true);
24
25
  }
25
26
  logger_1.default.warn('Blocked CORS origin', { origin });
26
- return callback(new Error('Not allowed by CORS: ' + origin));
27
+ // A 403, not a plain Error: that became a 500 logged as a server bug
28
+ // for what is only a page on another site calling in.
29
+ return callback(new HttpError_1.ForbiddenError('Origin not allowed'));
27
30
  },
28
31
  credentials: true,
29
32
  // PATCH belongs here as much as PUT: leaving it out lets the preflight
@@ -1 +1 @@
1
- {"version":3,"file":"corsMiddleware.js","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":";;;;;AAiCA,oDA+BC;AAhED,gDAAwB;AAExB,+DAAuC;AA0BvC;;;;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,OAAO,QAAQ,CAAC,IAAI,KAAK,CAAC,uBAAuB,GAAG,MAAM,CAAC,CAAC,CAAC;QAC/D,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,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"}
1
+ {"version":3,"file":"corsMiddleware.js","sourceRoot":"","sources":["../../src/middleware/corsMiddleware.ts"],"names":[],"mappings":";;;;;AAkCA,oDAiCC;AAnED,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,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"}
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,mBAAmB,EAAE,MAAM,SAAS,CAAC;AA8B/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,mBA6D1B,CAAC"}
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,mBAAmB,EAAE,MAAM,SAAS,CAAC;AA8B/E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,EAAE,mBA0D1B,CAAC"}
@@ -58,14 +58,11 @@ const errorHandler = (error, req, res, _next) => {
58
58
  correlationId: req.correlationId
59
59
  });
60
60
  }
61
- // Add CORS headers to error responses
62
- const origin = req.headers.origin;
63
- if (origin && (origin.includes('localhost') || origin.includes('tumbaland.eu'))) {
64
- res.header('Access-Control-Allow-Origin', origin);
65
- res.header('Access-Control-Allow-Credentials', 'true');
66
- res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
67
- res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, x-correlation-id, x-session-id');
68
- }
61
+ // No CORS headers here. The CORS middleware sets them for an allowed origin
62
+ // before the route runs, so an error response already carries them. This
63
+ // used to add them again for any origin that merely *contained*
64
+ // "tumbaland.eu" or "localhost", which let https://tumbaland.eu.example.com
65
+ // read error responses with the visitor's cookies.
69
66
  if (known) {
70
67
  res.status(known.statusCode).json({
71
68
  // Spread first so a stray details key can't shadow the envelope fields
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":";;;;;;AACA,+DAAuC;AACvC,mDAAgD;AAUhD;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,KAAY;IACjC,IAAI,KAAK,YAAY,qBAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC5G,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACnE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACI,MAAM,YAAY,GAAwB,CAC/C,KAAY,EACZ,GAAY,EACZ,GAAa,EACb,KAAmB,EACb,EAAE;IACR,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEnC,IAAI,KAAK,EAAE,CAAC;QACV,uEAAuE;QACvE,kEAAkE;QAClE,gBAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC7B,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,aAAa,EAAE,GAAG,CAAC,aAAa;SACjC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,gBAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE;YAC/B,KAAK,EAAE,KAAK,CAAC,OAAO;YACpB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC;YAChC,aAAa,EAAE,GAAG,CAAC,aAAa;SACjC,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,gEAAgE;IAChE,4EAA4E;IAC5E,mDAAmD;IAEnD,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;YAChC,uEAAuE;YACvE,kCAAkC;YAClC,GAAG,KAAK,CAAC,OAAO;YAChB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,+DAA+D;IAC/D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;IAC7D,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAE5E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,uBAAuB;QAC9B,OAAO,EAAE,YAAY;QACrB,GAAG,CAAC,aAAa,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC,CAAC;AA1DW,QAAA,YAAY,gBA0DvB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Makes typed search text match literally inside a Mongo `$regex`.
3
+ *
4
+ * Unescaped, a search for "c++" or ":)" is an invalid pattern and the request
5
+ * fails with a 500, and a crafted one can keep the database busy backtracking.
6
+ */
7
+ export declare const escapeRegex: (text: string) => string;
8
+ //# sourceMappingURL=escapeRegex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escapeRegex.d.ts","sourceRoot":"","sources":["../../src/utils/escapeRegex.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,KAAG,MAAqD,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.escapeRegex = void 0;
4
+ /**
5
+ * Makes typed search text match literally inside a Mongo `$regex`.
6
+ *
7
+ * Unescaped, a search for "c++" or ":)" is an invalid pattern and the request
8
+ * fails with a 500, and a crafted one can keep the database busy backtracking.
9
+ */
10
+ const escapeRegex = (text) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
11
+ exports.escapeRegex = escapeRegex;
12
+ //# sourceMappingURL=escapeRegex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escapeRegex.js","sourceRoot":"","sources":["../../src/utils/escapeRegex.ts"],"names":[],"mappings":";;;AAAA;;;;;GAKG;AACI,MAAM,WAAW,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAApF,QAAA,WAAW,eAAyE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tumbaland/backend-core",
3
- "version": "1.45.0",
3
+ "version": "1.46.0",
4
4
  "description": "Core shared functionality for Tumbaland backend services",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",