@carlonicora/nestjs-neo4jsonapi 6.6.1 → 6.6.2
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/common/decorators/index.d.ts +1 -0
- package/dist/common/decorators/index.d.ts.map +1 -1
- package/dist/common/decorators/index.js +1 -0
- package/dist/common/decorators/index.js.map +1 -1
- package/dist/common/decorators/token-scopes.decorator.d.ts +14 -0
- package/dist/common/decorators/token-scopes.decorator.d.ts.map +1 -0
- package/dist/common/decorators/token-scopes.decorator.js +18 -0
- package/dist/common/decorators/token-scopes.decorator.js.map +1 -0
- package/dist/common/guards/index.d.ts +1 -0
- package/dist/common/guards/index.d.ts.map +1 -1
- package/dist/common/guards/index.js +1 -0
- package/dist/common/guards/index.js.map +1 -1
- package/dist/common/guards/jwt.auth.admin.guard.d.ts.map +1 -1
- package/dist/common/guards/jwt.auth.admin.guard.js +20 -5
- package/dist/common/guards/jwt.auth.admin.guard.js.map +1 -1
- package/dist/common/guards/jwt.auth.any-scope.guard.d.ts +10 -3
- package/dist/common/guards/jwt.auth.any-scope.guard.d.ts.map +1 -1
- package/dist/common/guards/jwt.auth.any-scope.guard.js +17 -4
- package/dist/common/guards/jwt.auth.any-scope.guard.js.map +1 -1
- package/dist/common/guards/jwt.auth.guard.d.ts.map +1 -1
- package/dist/common/guards/jwt.auth.guard.js +22 -6
- package/dist/common/guards/jwt.auth.guard.js.map +1 -1
- package/dist/common/guards/jwt.auth.optional.guard.d.ts.map +1 -1
- package/dist/common/guards/jwt.auth.optional.guard.js +20 -5
- package/dist/common/guards/jwt.auth.optional.guard.js.map +1 -1
- package/dist/common/guards/session.token.d.ts +50 -0
- package/dist/common/guards/session.token.d.ts.map +1 -0
- package/dist/common/guards/session.token.js +71 -0
- package/dist/common/guards/session.token.js.map +1 -0
- package/dist/common/strategies/jwt.strategy.d.ts +8 -0
- package/dist/common/strategies/jwt.strategy.d.ts.map +1 -1
- package/dist/common/strategies/jwt.strategy.js +8 -0
- package/dist/common/strategies/jwt.strategy.js.map +1 -1
- package/dist/core/websocket/gateways/event.gateway.d.ts.map +1 -1
- package/dist/core/websocket/gateways/event.gateway.js +12 -1
- package/dist/core/websocket/gateways/event.gateway.js.map +1 -1
- package/dist/core/websocket/guards/ws.jwt.auth.guard.d.ts.map +1 -1
- package/dist/core/websocket/guards/ws.jwt.auth.guard.js +4 -0
- package/dist/core/websocket/guards/ws.jwt.auth.guard.js.map +1 -1
- package/dist/foundations/auth/controllers/auth.company.controller.d.ts.map +1 -1
- package/dist/foundations/auth/controllers/auth.company.controller.js +4 -0
- package/dist/foundations/auth/controllers/auth.company.controller.js.map +1 -1
- package/dist/foundations/auth/repositories/auth.repository.d.ts.map +1 -1
- package/dist/foundations/auth/repositories/auth.repository.js +5 -0
- package/dist/foundations/auth/repositories/auth.repository.js.map +1 -1
- package/dist/foundations/chunk/controllers/chunk.controller.d.ts.map +1 -1
- package/dist/foundations/chunk/controllers/chunk.controller.js +7 -0
- package/dist/foundations/chunk/controllers/chunk.controller.js.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts +13 -0
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.js +27 -1
- package/dist/foundations/chunk/repositories/chunk.repository.js.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.d.ts +48 -7
- package/dist/foundations/chunker/services/chunker.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.js +119 -61
- package/dist/foundations/chunker/services/chunker.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/docx.service.d.ts +2 -0
- package/dist/foundations/chunker/services/types/docx.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/docx.service.js +10 -36
- package/dist/foundations/chunker/services/types/docx.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/pptx.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/pptx.service.js +5 -0
- package/dist/foundations/chunker/services/types/pptx.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/xlsx.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/xlsx.service.js +8 -1
- package/dist/foundations/chunker/services/types/xlsx.service.js.map +1 -1
- package/dist/foundations/chunker/utils/zip-limits.d.ts +37 -0
- package/dist/foundations/chunker/utils/zip-limits.d.ts.map +1 -0
- package/dist/foundations/chunker/utils/zip-limits.js +113 -0
- package/dist/foundations/chunker/utils/zip-limits.js.map +1 -0
- package/dist/foundations/oauth/constants/oauth.errors.d.ts +5 -0
- package/dist/foundations/oauth/constants/oauth.errors.d.ts.map +1 -1
- package/dist/foundations/oauth/constants/oauth.errors.js +6 -0
- package/dist/foundations/oauth/constants/oauth.errors.js.map +1 -1
- package/dist/foundations/oauth/controllers/oauth.registration.controller.d.ts.map +1 -1
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js +10 -1
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js.map +1 -1
- package/dist/foundations/oauth/queries/revoke-user-oauth-tokens.query.d.ts +13 -0
- package/dist/foundations/oauth/queries/revoke-user-oauth-tokens.query.d.ts.map +1 -0
- package/dist/foundations/oauth/queries/revoke-user-oauth-tokens.query.js +29 -0
- package/dist/foundations/oauth/queries/revoke-user-oauth-tokens.query.js.map +1 -0
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts +22 -0
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts.map +1 -1
- package/dist/foundations/oauth/repositories/oauth.repository.js +43 -12
- package/dist/foundations/oauth/repositories/oauth.repository.js.map +1 -1
- package/dist/foundations/oauth/services/oauth.service.d.ts.map +1 -1
- package/dist/foundations/oauth/services/oauth.service.js +11 -2
- package/dist/foundations/oauth/services/oauth.service.js.map +1 -1
- package/dist/foundations/oauth/services/oauth.token.service.d.ts +9 -0
- package/dist/foundations/oauth/services/oauth.token.service.d.ts.map +1 -1
- package/dist/foundations/oauth/services/oauth.token.service.js +22 -0
- package/dist/foundations/oauth/services/oauth.token.service.js.map +1 -1
- package/dist/foundations/s3/controllers/s3.controller.d.ts +13 -0
- package/dist/foundations/s3/controllers/s3.controller.d.ts.map +1 -1
- package/dist/foundations/s3/controllers/s3.controller.js +58 -7
- package/dist/foundations/s3/controllers/s3.controller.js.map +1 -1
- package/dist/foundations/user/repositories/user.repository.d.ts +18 -0
- package/dist/foundations/user/repositories/user.repository.d.ts.map +1 -1
- package/dist/foundations/user/repositories/user.repository.js +44 -1
- package/dist/foundations/user/repositories/user.repository.js.map +1 -1
- package/dist/mcp/controllers/mcp.controller.d.ts.map +1 -1
- package/dist/mcp/controllers/mcp.controller.js +7 -1
- package/dist/mcp/controllers/mcp.controller.js.map +1 -1
- package/package.json +1 -1
|
@@ -43,7 +43,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
43
43
|
exports.PptxService = void 0;
|
|
44
44
|
const common_1 = require("@nestjs/common");
|
|
45
45
|
const documents_1 = require("@langchain/core/documents");
|
|
46
|
+
const fs = __importStar(require("fs/promises"));
|
|
46
47
|
const officeParser = __importStar(require("officeparser"));
|
|
48
|
+
const zip_limits_1 = require("../../utils/zip-limits");
|
|
47
49
|
let PptxService = PptxService_1 = class PptxService {
|
|
48
50
|
constructor() {
|
|
49
51
|
this.logger = new common_1.Logger(PptxService_1.name);
|
|
@@ -125,6 +127,9 @@ let PptxService = PptxService_1 = class PptxService {
|
|
|
125
127
|
return result;
|
|
126
128
|
}
|
|
127
129
|
async extractPptxContent(pptxPath) {
|
|
130
|
+
// A PPTX is a zip: refuse one that expands beyond the zip limits BEFORE officeparser inflates it
|
|
131
|
+
// (outside the try below, so the refusal reaches the caller instead of reading as "empty").
|
|
132
|
+
await (0, zip_limits_1.loadZipWithinLimits)({ buffer: await fs.readFile(pptxPath), label: "PPTX" });
|
|
128
133
|
try {
|
|
129
134
|
const ast = await officeParser.parseOffice(pptxPath, { ignoreNotes: false });
|
|
130
135
|
return ast?.toText() || "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pptx.service.js","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/pptx.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,yDAAqD;AACrD,2DAA6C;
|
|
1
|
+
{"version":3,"file":"pptx.service.js","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/pptx.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xlsx.service.d.ts","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/xlsx.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"xlsx.service.d.ts","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/xlsx.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AAGvC,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;CACpB;AAED,qBACa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IAEhD,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,GAAG,MAAM;IA0CzD,uBAAuB,CAAC,aAAa,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE;IA2BxE,OAAO,CAAC,kBAAkB;IAmE1B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,0BAA0B;IAuD5B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA+C9D,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjD,IAAI,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAmC9D"}
|
|
@@ -43,7 +43,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
43
43
|
exports.XlsxService = void 0;
|
|
44
44
|
const common_1 = require("@nestjs/common");
|
|
45
45
|
const documents_1 = require("@langchain/core/documents");
|
|
46
|
+
const fs = __importStar(require("fs/promises"));
|
|
46
47
|
const XLSX = __importStar(require("xlsx-republish"));
|
|
48
|
+
const zip_limits_1 = require("../../utils/zip-limits");
|
|
47
49
|
let XlsxService = XlsxService_1 = class XlsxService {
|
|
48
50
|
constructor() {
|
|
49
51
|
this.logger = new common_1.Logger(XlsxService_1.name);
|
|
@@ -211,9 +213,14 @@ let XlsxService = XlsxService_1 = class XlsxService {
|
|
|
211
213
|
return [headerRow, separatorRow, ...markdownRows].join("\n");
|
|
212
214
|
}
|
|
213
215
|
async extractXlsxContent(xlsxPath) {
|
|
216
|
+
// An XLSX is a zip: refuse one that expands beyond the zip limits BEFORE SheetJS inflates it
|
|
217
|
+
// (outside the try below, so the refusal reaches the caller instead of reading as "empty").
|
|
218
|
+
// A non-zip spreadsheet (legacy .xls, CSV) has nothing to inflate and is parsed as before.
|
|
219
|
+
const buffer = await fs.readFile(xlsxPath);
|
|
220
|
+
await (0, zip_limits_1.loadZipWithinLimits)({ buffer, label: "XLSX" });
|
|
214
221
|
try {
|
|
215
222
|
// Read the Excel file
|
|
216
|
-
const workbook = XLSX.
|
|
223
|
+
const workbook = XLSX.read(buffer, { type: "buffer" });
|
|
217
224
|
const worksheetData = [];
|
|
218
225
|
// Process each worksheet
|
|
219
226
|
for (const sheetName of workbook.SheetNames) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xlsx.service.js","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/xlsx.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,yDAAqD;AACrD,qDAAuC;
|
|
1
|
+
{"version":3,"file":"xlsx.service.js","sourceRoot":"","sources":["../../../../../src/foundations/chunker/services/types/xlsx.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import JSZip from "jszip";
|
|
2
|
+
/**
|
|
3
|
+
* Ceilings on what an uploaded OOXML file (DOCX, XLSX: both are zip archives) may expand to
|
|
4
|
+
* before the chunker parses it.
|
|
5
|
+
*
|
|
6
|
+
* A small archive can declare, or simply inflate to, gigabytes (a decompression bomb). The parsers
|
|
7
|
+
* downstream hold whole parts in memory (`document.xml` as one string and then one XML tree; SheetJS
|
|
8
|
+
* the whole workbook), so an uncapped expansion takes the API or worker process down.
|
|
9
|
+
*
|
|
10
|
+
* - Per entry, 64 MiB: the largest single part the chunker accepts. `word/document.xml` for a
|
|
11
|
+
* 2,000-page legal document is in the tens of MiB; one part beyond that is not a real document.
|
|
12
|
+
* - Total, 256 MiB: every part together. Embedded media barely compresses, so a genuine file
|
|
13
|
+
* expands to roughly its stored size; the upload cap is 100 MB, and 256 MiB leaves room for
|
|
14
|
+
* heavily compressed XML around it while staying far below the worker heap.
|
|
15
|
+
*/
|
|
16
|
+
export declare const ZIP_MAX_ENTRY_UNCOMPRESSED_BYTES: number;
|
|
17
|
+
export declare const ZIP_MAX_TOTAL_UNCOMPRESSED_BYTES: number;
|
|
18
|
+
/** The archive `loadZipWithinLimits` returns. */
|
|
19
|
+
export type LoadedZip = JSZip;
|
|
20
|
+
export interface ZipLimits {
|
|
21
|
+
maxEntryBytes: number;
|
|
22
|
+
maxTotalBytes: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Loads `buffer` as a zip and refuses it (BadRequestException) when any entry, or the archive as a
|
|
26
|
+
* whole, expands beyond the limits. Checks the declared sizes first (cheap, no inflation), then
|
|
27
|
+
* inflates every entry with a running counter, since a crafted archive can declare small sizes and
|
|
28
|
+
* still inflate without bound. Returns the loaded archive, which is then safe to read.
|
|
29
|
+
*
|
|
30
|
+
* Returns `undefined` when `buffer` is not a zip at all; the caller decides what that means.
|
|
31
|
+
*/
|
|
32
|
+
export declare function loadZipWithinLimits(params: {
|
|
33
|
+
buffer: Buffer;
|
|
34
|
+
label: string;
|
|
35
|
+
limits?: Partial<ZipLimits>;
|
|
36
|
+
}): Promise<JSZip | undefined>;
|
|
37
|
+
//# sourceMappingURL=zip-limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-limits.d.ts","sourceRoot":"","sources":["../../../../src/foundations/chunker/utils/zip-limits.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gCAAgC,QAAmB,CAAC;AACjE,eAAO,MAAM,gCAAgC,QAAoB,CAAC;AAElE,iDAAiD;AACjD,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC;AAE9B,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAiED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;CAC7B,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CA0B7B"}
|
|
@@ -0,0 +1,113 @@
|
|
|
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.ZIP_MAX_TOTAL_UNCOMPRESSED_BYTES = exports.ZIP_MAX_ENTRY_UNCOMPRESSED_BYTES = void 0;
|
|
7
|
+
exports.loadZipWithinLimits = loadZipWithinLimits;
|
|
8
|
+
const common_1 = require("@nestjs/common");
|
|
9
|
+
const jszip_1 = __importDefault(require("jszip"));
|
|
10
|
+
/**
|
|
11
|
+
* Ceilings on what an uploaded OOXML file (DOCX, XLSX: both are zip archives) may expand to
|
|
12
|
+
* before the chunker parses it.
|
|
13
|
+
*
|
|
14
|
+
* A small archive can declare, or simply inflate to, gigabytes (a decompression bomb). The parsers
|
|
15
|
+
* downstream hold whole parts in memory (`document.xml` as one string and then one XML tree; SheetJS
|
|
16
|
+
* the whole workbook), so an uncapped expansion takes the API or worker process down.
|
|
17
|
+
*
|
|
18
|
+
* - Per entry, 64 MiB: the largest single part the chunker accepts. `word/document.xml` for a
|
|
19
|
+
* 2,000-page legal document is in the tens of MiB; one part beyond that is not a real document.
|
|
20
|
+
* - Total, 256 MiB: every part together. Embedded media barely compresses, so a genuine file
|
|
21
|
+
* expands to roughly its stored size; the upload cap is 100 MB, and 256 MiB leaves room for
|
|
22
|
+
* heavily compressed XML around it while staying far below the worker heap.
|
|
23
|
+
*/
|
|
24
|
+
exports.ZIP_MAX_ENTRY_UNCOMPRESSED_BYTES = 64 * 1024 * 1024;
|
|
25
|
+
exports.ZIP_MAX_TOTAL_UNCOMPRESSED_BYTES = 256 * 1024 * 1024;
|
|
26
|
+
const DEFAULT_LIMITS = {
|
|
27
|
+
maxEntryBytes: exports.ZIP_MAX_ENTRY_UNCOMPRESSED_BYTES,
|
|
28
|
+
maxTotalBytes: exports.ZIP_MAX_TOTAL_UNCOMPRESSED_BYTES,
|
|
29
|
+
};
|
|
30
|
+
/** The size the central directory declares for an entry. JSZip keeps it on the private `_data`. */
|
|
31
|
+
function declaredSize(entry) {
|
|
32
|
+
const size = entry._data?.uncompressedSize;
|
|
33
|
+
return typeof size === "number" && Number.isFinite(size) && size >= 0 ? size : 0;
|
|
34
|
+
}
|
|
35
|
+
function tooLarge(label, name, limit) {
|
|
36
|
+
return new common_1.BadRequestException(name
|
|
37
|
+
? `${label}: entry ${name} expands beyond ${limit} bytes`
|
|
38
|
+
: `${label}: archive expands beyond ${limit} bytes in total`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Inflates one entry while counting, discarding the bytes. Rejects as soon as the entry passes the
|
|
42
|
+
* per-entry cap or the running archive total passes the total cap; the declared size is not trusted.
|
|
43
|
+
*/
|
|
44
|
+
function countEntry(params) {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const stream = params.entry.nodeStream("nodebuffer");
|
|
47
|
+
let entryBytes = 0;
|
|
48
|
+
let settled = false;
|
|
49
|
+
const stop = (error) => {
|
|
50
|
+
if (settled)
|
|
51
|
+
return;
|
|
52
|
+
settled = true;
|
|
53
|
+
stream.pause();
|
|
54
|
+
stream.removeAllListeners("data");
|
|
55
|
+
reject(error);
|
|
56
|
+
};
|
|
57
|
+
stream.on("data", (chunk) => {
|
|
58
|
+
entryBytes += chunk.length;
|
|
59
|
+
if (entryBytes > params.limits.maxEntryBytes)
|
|
60
|
+
return stop(tooLarge(params.label, params.entry.name, params.limits.maxEntryBytes));
|
|
61
|
+
if (params.totalSoFar + entryBytes > params.limits.maxTotalBytes)
|
|
62
|
+
return stop(tooLarge(params.label, undefined, params.limits.maxTotalBytes));
|
|
63
|
+
});
|
|
64
|
+
// JSZip fails an entry whose inflated length differs from the declared one ("uncompressed data
|
|
65
|
+
// size mismatch") or whose data is corrupt: an archive that lies about its sizes is refused too.
|
|
66
|
+
stream.on("error", (error) => {
|
|
67
|
+
if (settled)
|
|
68
|
+
return;
|
|
69
|
+
settled = true;
|
|
70
|
+
reject(new common_1.BadRequestException(`${params.label}: entry ${params.entry.name} is corrupt (${error.message})`));
|
|
71
|
+
});
|
|
72
|
+
stream.on("end", () => {
|
|
73
|
+
if (settled)
|
|
74
|
+
return;
|
|
75
|
+
settled = true;
|
|
76
|
+
resolve(entryBytes);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Loads `buffer` as a zip and refuses it (BadRequestException) when any entry, or the archive as a
|
|
82
|
+
* whole, expands beyond the limits. Checks the declared sizes first (cheap, no inflation), then
|
|
83
|
+
* inflates every entry with a running counter, since a crafted archive can declare small sizes and
|
|
84
|
+
* still inflate without bound. Returns the loaded archive, which is then safe to read.
|
|
85
|
+
*
|
|
86
|
+
* Returns `undefined` when `buffer` is not a zip at all; the caller decides what that means.
|
|
87
|
+
*/
|
|
88
|
+
async function loadZipWithinLimits(params) {
|
|
89
|
+
const limits = { ...DEFAULT_LIMITS, ...params.limits };
|
|
90
|
+
let zip;
|
|
91
|
+
try {
|
|
92
|
+
zip = await jszip_1.default.loadAsync(params.buffer);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const entries = Object.values(zip.files).filter((entry) => !entry.dir);
|
|
98
|
+
let declaredTotal = 0;
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
const size = declaredSize(entry);
|
|
101
|
+
if (size > limits.maxEntryBytes)
|
|
102
|
+
throw tooLarge(params.label, entry.name, limits.maxEntryBytes);
|
|
103
|
+
declaredTotal += size;
|
|
104
|
+
if (declaredTotal > limits.maxTotalBytes)
|
|
105
|
+
throw tooLarge(params.label, undefined, limits.maxTotalBytes);
|
|
106
|
+
}
|
|
107
|
+
let actualTotal = 0;
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
actualTotal += await countEntry({ entry, label: params.label, limits, totalSoFar: actualTotal });
|
|
110
|
+
}
|
|
111
|
+
return zip;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=zip-limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zip-limits.js","sourceRoot":"","sources":["../../../../src/foundations/chunker/utils/zip-limits.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,6 +58,11 @@ export declare const OAuthErrorCodes: {
|
|
|
58
58
|
* due to temporary overloading or maintenance of the server.
|
|
59
59
|
*/
|
|
60
60
|
readonly TEMPORARILY_UNAVAILABLE: "temporarily_unavailable";
|
|
61
|
+
/**
|
|
62
|
+
* The value of one of the client metadata fields is invalid (RFC 7591
|
|
63
|
+
* Section 3.2.2, Dynamic Client Registration).
|
|
64
|
+
*/
|
|
65
|
+
readonly INVALID_CLIENT_METADATA: "invalid_client_metadata";
|
|
61
66
|
};
|
|
62
67
|
export type OAuthErrorCode = (typeof OAuthErrorCodes)[keyof typeof OAuthErrorCodes];
|
|
63
68
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.errors.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/constants/oauth.errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;IAC1B;;;;OAIG;;IAGH;;;OAGG;;IAGH;;;;OAIG;;IAGH;;;OAGG;;IAGH;;OAEG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;CAEK,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth.errors.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/constants/oauth.errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;IAC1B;;;;OAIG;;IAGH;;;OAGG;;IAGH;;;;OAIG;;IAGH;;;OAGG;;IAGH;;OAEG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;CAEK,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAYjE,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAM7G"}
|
|
@@ -62,6 +62,11 @@ exports.OAuthErrorCodes = {
|
|
|
62
62
|
* due to temporary overloading or maintenance of the server.
|
|
63
63
|
*/
|
|
64
64
|
TEMPORARILY_UNAVAILABLE: "temporarily_unavailable",
|
|
65
|
+
/**
|
|
66
|
+
* The value of one of the client metadata fields is invalid (RFC 7591
|
|
67
|
+
* Section 3.2.2, Dynamic Client Registration).
|
|
68
|
+
*/
|
|
69
|
+
INVALID_CLIENT_METADATA: "invalid_client_metadata",
|
|
65
70
|
};
|
|
66
71
|
/**
|
|
67
72
|
* Human-readable error descriptions for OAuth error codes.
|
|
@@ -77,6 +82,7 @@ exports.OAuthErrorDescriptions = {
|
|
|
77
82
|
[exports.OAuthErrorCodes.UNSUPPORTED_RESPONSE_TYPE]: "The response type is not supported.",
|
|
78
83
|
[exports.OAuthErrorCodes.SERVER_ERROR]: "An unexpected error occurred on the authorization server.",
|
|
79
84
|
[exports.OAuthErrorCodes.TEMPORARILY_UNAVAILABLE]: "The authorization server is temporarily unavailable.",
|
|
85
|
+
[exports.OAuthErrorCodes.INVALID_CLIENT_METADATA]: "A client metadata field is invalid.",
|
|
80
86
|
};
|
|
81
87
|
/**
|
|
82
88
|
* Creates a standard OAuth error response object.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.errors.js","sourceRoot":"","sources":["../../../../src/foundations/oauth/constants/oauth.errors.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"oauth.errors.js","sourceRoot":"","sources":["../../../../src/foundations/oauth/constants/oauth.errors.ts"],"names":[],"mappings":";;;AA+GA,4CAMC;AArHD;;;;;;;GAOG;AACU,QAAA,eAAe,GAAG;IAC7B;;;;OAIG;IACH,eAAe,EAAE,iBAAiB;IAElC;;;OAGG;IACH,cAAc,EAAE,gBAAgB;IAEhC;;;;OAIG;IACH,aAAa,EAAE,eAAe;IAE9B;;;OAGG;IACH,mBAAmB,EAAE,qBAAqB;IAE1C;;OAEG;IACH,sBAAsB,EAAE,wBAAwB;IAEhD;;;OAGG;IACH,aAAa,EAAE,eAAe;IAE9B;;;OAGG;IACH,aAAa,EAAE,eAAe;IAE9B;;;OAGG;IACH,yBAAyB,EAAE,2BAA2B;IAEtD;;;OAGG;IACH,YAAY,EAAE,cAAc;IAE5B;;;OAGG;IACH,uBAAuB,EAAE,yBAAyB;IAElD;;;OAGG;IACH,uBAAuB,EAAE,yBAAyB;CAC1C,CAAC;AAIX;;GAEG;AACU,QAAA,sBAAsB,GAAmC;IACpE,CAAC,uBAAe,CAAC,eAAe,CAAC,EAAE,wEAAwE;IAC3G,CAAC,uBAAe,CAAC,cAAc,CAAC,EAAE,+BAA+B;IACjE,CAAC,uBAAe,CAAC,aAAa,CAAC,EAAE,yEAAyE;IAC1G,CAAC,uBAAe,CAAC,mBAAmB,CAAC,EAAE,sDAAsD;IAC7F,CAAC,uBAAe,CAAC,sBAAsB,CAAC,EAAE,kCAAkC;IAC5E,CAAC,uBAAe,CAAC,aAAa,CAAC,EAAE,8DAA8D;IAC/F,CAAC,uBAAe,CAAC,aAAa,CAAC,EAAE,wCAAwC;IACzE,CAAC,uBAAe,CAAC,yBAAyB,CAAC,EAAE,qCAAqC;IAClF,CAAC,uBAAe,CAAC,YAAY,CAAC,EAAE,2DAA2D;IAC3F,CAAC,uBAAe,CAAC,uBAAuB,CAAC,EAAE,sDAAsD;IACjG,CAAC,uBAAe,CAAC,uBAAuB,CAAC,EAAE,qCAAqC;CACjF,CAAC;AAWF;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,IAAoB,EAAE,WAAoB,EAAE,GAAY;IACvF,OAAO;QACL,KAAK,EAAE,IAAI;QACX,iBAAiB,EAAE,WAAW,IAAI,8BAAsB,CAAC,IAAI,CAAC;QAC9D,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;KAC/B,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.registration.controller.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/controllers/oauth.registration.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"oauth.registration.controller.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/controllers/oauth.registration.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAItE;;;;;;;;;GASG;AACH,qBAEa,2BAA2B;IAEpC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa;gBADb,aAAa,EAAE,kBAAkB,EACjC,aAAa,EAAE,aAAa;IAG/C;;;;;;;OAOG;IAGG,QAAQ,CAAS,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC;QACrD,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,0BAA0B,EAAE,MAAM,CAAC;QACnC,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CAwCH"}
|
|
@@ -18,6 +18,8 @@ const oauth_error_filter_1 = require("../filters/oauth.error.filter");
|
|
|
18
18
|
const config_1 = require("@nestjs/config");
|
|
19
19
|
const oauth_register_dto_1 = require("../dtos/oauth.register.dto");
|
|
20
20
|
const oauth_client_service_1 = require("../services/oauth.client.service");
|
|
21
|
+
const oauth_scopes_1 = require("../constants/oauth.scopes");
|
|
22
|
+
const oauth_errors_1 = require("../constants/oauth.errors");
|
|
21
23
|
/**
|
|
22
24
|
* OAuth Dynamic Client Registration Controller
|
|
23
25
|
*
|
|
@@ -46,11 +48,18 @@ let OAuthRegistrationController = class OAuthRegistrationController {
|
|
|
46
48
|
if (!oauth?.enabled) {
|
|
47
49
|
throw new common_1.HttpException("OAuth is not enabled", 404);
|
|
48
50
|
}
|
|
51
|
+
// Anyone can register (no credentials exist yet), so a registered client may
|
|
52
|
+
// only ever ask for the MCP scope. Without this an anonymous caller could
|
|
53
|
+
// register a client for `admin`, `read`, `write` or any app scope.
|
|
54
|
+
const requestedScopes = dto.scope ? (0, oauth_scopes_1.parseScopes)(dto.scope) : [];
|
|
55
|
+
if (requestedScopes.some((scope) => scope !== oauth_scopes_1.OAuth2Scopes.MCP)) {
|
|
56
|
+
throw new common_1.HttpException((0, oauth_errors_1.createOAuthError)(oauth_errors_1.OAuthErrorCodes.INVALID_CLIENT_METADATA, `Dynamically registered clients may only request the "${oauth_scopes_1.OAuth2Scopes.MCP}" scope`), 400);
|
|
57
|
+
}
|
|
49
58
|
const isConfidential = dto.token_endpoint_auth_method !== undefined && dto.token_endpoint_auth_method !== "none";
|
|
50
59
|
const { client, clientSecret } = await this.clientService.createClient({
|
|
51
60
|
name: dto.client_name ?? "Dynamically registered client",
|
|
52
61
|
redirectUris: dto.redirect_uris,
|
|
53
|
-
allowedScopes:
|
|
62
|
+
allowedScopes: [oauth_scopes_1.OAuth2Scopes.MCP],
|
|
54
63
|
allowedGrantTypes: dto.grant_types ?? ["authorization_code", "refresh_token"],
|
|
55
64
|
isConfidential,
|
|
56
65
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.registration.controller.js","sourceRoot":"","sources":["../../../../src/foundations/oauth/controllers/oauth.registration.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA6F;AAC7F,sEAAiE;AACjE,2CAA+C;AAE/C,mEAA8D;AAC9D,2EAAsE;
|
|
1
|
+
{"version":3,"file":"oauth.registration.controller.js","sourceRoot":"","sources":["../../../../src/foundations/oauth/controllers/oauth.registration.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA6F;AAC7F,sEAAiE;AACjE,2CAA+C;AAE/C,mEAA8D;AAC9D,2EAAsE;AACtE,4DAAsE;AACtE,4DAA8E;AAE9E;;;;;;;;;GASG;AAGI,IAAM,2BAA2B,GAAjC,MAAM,2BAA2B;IACtC,YACmB,aAAiC,EACjC,aAA4B;QAD5B,kBAAa,GAAb,aAAa,CAAoB;QACjC,kBAAa,GAAb,aAAa,CAAe;IAC5C,CAAC;IAEJ;;;;;;;OAOG;IAGG,AAAN,KAAK,CAAC,QAAQ,CAAS,GAAqB;QAS1C,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAuB,OAAO,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,sBAAa,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;QACvD,CAAC;QAED,6EAA6E;QAC7E,0EAA0E;QAC1E,mEAAmE;QACnE,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,0BAAW,EAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,2BAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,sBAAa,CACrB,IAAA,+BAAgB,EACd,8BAAe,CAAC,uBAAuB,EACvC,wDAAwD,2BAAY,CAAC,GAAG,SAAS,CAClF,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,cAAc,GAAG,GAAG,CAAC,0BAA0B,KAAK,SAAS,IAAI,GAAG,CAAC,0BAA0B,KAAK,MAAM,CAAC;QAEjH,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;YACrE,IAAI,EAAE,GAAG,CAAC,WAAW,IAAI,+BAA+B;YACxD,YAAY,EAAE,GAAG,CAAC,aAAa;YAC/B,aAAa,EAAE,CAAC,2BAAY,CAAC,GAAG,CAAC;YACjC,iBAAiB,EAAE,GAAG,CAAC,WAAW,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC;YAC7E,cAAc;SACf,CAAC,CAAC;QAEH,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,QAAQ;YAC1B,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,mBAAmB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAClD,aAAa,EAAE,MAAM,CAAC,YAAY;YAClC,WAAW,EAAE,MAAM,CAAC,iBAAiB;YACrC,0BAA0B,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,0BAA2B,CAAC,CAAC,CAAC,MAAM;YACrF,WAAW,EAAE,MAAM,CAAC,IAAI;SACzB,CAAC;IACJ,CAAC;CACF,CAAA;AAhEY,kEAA2B;AAgBhC;IAFL,IAAA,aAAI,EAAC,UAAU,CAAC;IAChB,IAAA,iBAAQ,EAAC,GAAG,CAAC;IACE,WAAA,IAAA,aAAI,GAAE,CAAA;;qCAAM,qCAAgB;;2DA+C3C;sCA/DU,2BAA2B;IAFvC,IAAA,mBAAU,EAAC,OAAO,CAAC;IACnB,IAAA,mBAAU,EAAC,qCAAgB,CAAC;qCAGO,yCAAkB;QAClB,sBAAa;GAHpC,2BAA2B,CAgEvC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cypher that revokes every OAuth access and refresh token of `userAlias`
|
|
3
|
+
* (MCP and other OAuth clients), across every company: deletion and a password
|
|
4
|
+
* change or reset end all of the user's delegated access, not one company's.
|
|
5
|
+
* Tokens are matched on their `userId` property, not on an edge, so the clause
|
|
6
|
+
* also works right before the User node is hard-deleted. Unit subqueries: the
|
|
7
|
+
* outer row passes through unchanged, and the revocation runs only for a row
|
|
8
|
+
* that reached it (the write matched its user). The caller emits the `WITH`
|
|
9
|
+
* that carries `userAlias` (and any other alias it still needs) right before
|
|
10
|
+
* this clause.
|
|
11
|
+
*/
|
|
12
|
+
export declare function revokeUserOAuthTokensClause(userAlias?: string): string;
|
|
13
|
+
//# sourceMappingURL=revoke-user-oauth-tokens.query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke-user-oauth-tokens.query.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/queries/revoke-user-oauth-tokens.query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,SAAS,GAAG,MAAM,CAatE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.revokeUserOAuthTokensClause = revokeUserOAuthTokensClause;
|
|
4
|
+
/**
|
|
5
|
+
* Cypher that revokes every OAuth access and refresh token of `userAlias`
|
|
6
|
+
* (MCP and other OAuth clients), across every company: deletion and a password
|
|
7
|
+
* change or reset end all of the user's delegated access, not one company's.
|
|
8
|
+
* Tokens are matched on their `userId` property, not on an edge, so the clause
|
|
9
|
+
* also works right before the User node is hard-deleted. Unit subqueries: the
|
|
10
|
+
* outer row passes through unchanged, and the revocation runs only for a row
|
|
11
|
+
* that reached it (the write matched its user). The caller emits the `WITH`
|
|
12
|
+
* that carries `userAlias` (and any other alias it still needs) right before
|
|
13
|
+
* this clause.
|
|
14
|
+
*/
|
|
15
|
+
function revokeUserOAuthTokensClause(userAlias = "user") {
|
|
16
|
+
return `
|
|
17
|
+
CALL {
|
|
18
|
+
WITH ${userAlias}
|
|
19
|
+
MATCH (revoked_access:OAuthAccessToken {userId: ${userAlias}.id})
|
|
20
|
+
SET revoked_access.isRevoked = true, revoked_access.updatedAt = datetime()
|
|
21
|
+
}
|
|
22
|
+
CALL {
|
|
23
|
+
WITH ${userAlias}
|
|
24
|
+
MATCH (revoked_refresh:OAuthRefreshToken {userId: ${userAlias}.id})
|
|
25
|
+
SET revoked_refresh.isRevoked = true, revoked_refresh.updatedAt = datetime()
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=revoke-user-oauth-tokens.query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke-user-oauth-tokens.query.js","sourceRoot":"","sources":["../../../../src/foundations/oauth/queries/revoke-user-oauth-tokens.query.ts"],"names":[],"mappings":";;AAWA,kEAaC;AAxBD;;;;;;;;;;GAUG;AACH,SAAgB,2BAA2B,CAAC,SAAS,GAAG,MAAM;IAC5D,OAAO;;eAEM,SAAS;0DACkC,SAAS;;;;eAIpD,SAAS;4DACoC,SAAS;;;KAGhE,CAAC;AACN,CAAC"}
|
|
@@ -51,6 +51,18 @@ export declare class OAuthRepository implements OnModuleInit {
|
|
|
51
51
|
companyId?: string | null;
|
|
52
52
|
}): Promise<void>;
|
|
53
53
|
findAuthorizationCodeByHash(codeHash: string): Promise<OAuthAuthorizationCode | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Marks an authorization code as used. Returns true only for the request that
|
|
56
|
+
* flips `isUsed` from false to true; every later (or concurrent) redemption
|
|
57
|
+
* gets false.
|
|
58
|
+
*
|
|
59
|
+
* The write lock is taken BEFORE `isUsed` is read (`SET ... _lock` then
|
|
60
|
+
* `REMOVE`, the Neo4j lost-update pattern): two concurrent transactions
|
|
61
|
+
* serialise on the lock, and the second one reads the committed
|
|
62
|
+
* `isUsed = true` and matches zero rows. The query has a serialiser, so
|
|
63
|
+
* `writeOne` returns null on zero rows (without one it always returned null
|
|
64
|
+
* and the result could not tell a first use from a replay).
|
|
65
|
+
*/
|
|
54
66
|
markAuthorizationCodeUsed(codeHash: string): Promise<boolean>;
|
|
55
67
|
deleteExpiredAuthorizationCodes(): Promise<void>;
|
|
56
68
|
createAccessToken(params: {
|
|
@@ -77,6 +89,16 @@ export declare class OAuthRepository implements OnModuleInit {
|
|
|
77
89
|
revokeRefreshToken(tokenHash: string): Promise<void>;
|
|
78
90
|
revokeAllUserTokensForClient(userId: string, clientId: string): Promise<void>;
|
|
79
91
|
deleteExpiredTokens(): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Whether the user a token was issued to may still use it: the user exists,
|
|
94
|
+
* is not deleted, is active and, when the token carries a company, still
|
|
95
|
+
* BELONGS_TO that company. A token without a company (a platform user with no
|
|
96
|
+
* company) only needs the user checks.
|
|
97
|
+
*/
|
|
98
|
+
isTokenSubjectAuthorised(params: {
|
|
99
|
+
userId: string;
|
|
100
|
+
companyId: string | null;
|
|
101
|
+
}): Promise<boolean>;
|
|
80
102
|
/**
|
|
81
103
|
* Looks up the company ID for a user.
|
|
82
104
|
* Used to include companyId in OAuth tokens for proper scoping.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/repositories/oauth.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAG1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6CAA6C,CAAC;AAErF,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAG3E,qBACa,eAAgB,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,YAAY;IAE1C,YAAY;IAiCZ,YAAY,CAAC,MAAM,EAAE;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;QACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,sFAAsF;QACtF,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAwErD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAgBnE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAgBvD,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAY7D,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC,GACD,OAAO,CAAC,WAAW,CAAC;IAmCjB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAe3E,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB7C,uBAAuB,CAAC,MAAM,EAAE;QACpC,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACvC,SAAS,EAAE,IAAI,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,OAAO,CAAC,IAAI,CAAC;IA4CX,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"oauth.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/oauth/repositories/oauth.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -313,22 +313,32 @@ let OAuthRepository = class OAuthRepository {
|
|
|
313
313
|
return null;
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Marks an authorization code as used. Returns true only for the request that
|
|
318
|
+
* flips `isUsed` from false to true; every later (or concurrent) redemption
|
|
319
|
+
* gets false.
|
|
320
|
+
*
|
|
321
|
+
* The write lock is taken BEFORE `isUsed` is read (`SET ... _lock` then
|
|
322
|
+
* `REMOVE`, the Neo4j lost-update pattern): two concurrent transactions
|
|
323
|
+
* serialise on the lock, and the second one reads the committed
|
|
324
|
+
* `isUsed = true` and matches zero rows. The query has a serialiser, so
|
|
325
|
+
* `writeOne` returns null on zero rows (without one it always returned null
|
|
326
|
+
* and the result could not tell a first use from a replay).
|
|
327
|
+
*/
|
|
316
328
|
async markAuthorizationCodeUsed(codeHash) {
|
|
317
|
-
|
|
318
|
-
const query = this.neo4j.initQuery();
|
|
329
|
+
const query = this.neo4j.initQuery({ serialiser: oauth_authorization_code_model_1.OAuthAuthorizationCodeModel });
|
|
319
330
|
query.queryParams = { codeHash };
|
|
320
331
|
query.query = `
|
|
321
|
-
MATCH (
|
|
322
|
-
SET
|
|
323
|
-
|
|
332
|
+
MATCH (oauthauthorizationcode:OAuthAuthorizationCode {codeHash: $codeHash})
|
|
333
|
+
SET oauthauthorizationcode._lock = true
|
|
334
|
+
REMOVE oauthauthorizationcode._lock
|
|
335
|
+
WITH oauthauthorizationcode
|
|
336
|
+
WHERE oauthauthorizationcode.isUsed = false
|
|
337
|
+
SET oauthauthorizationcode.isUsed = true
|
|
338
|
+
RETURN oauthauthorizationcode
|
|
324
339
|
`;
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
catch {
|
|
330
|
-
return false;
|
|
331
|
-
}
|
|
340
|
+
const code = await this.neo4j.writeOne(query);
|
|
341
|
+
return code !== null && code !== undefined;
|
|
332
342
|
}
|
|
333
343
|
async deleteExpiredAuthorizationCodes() {
|
|
334
344
|
const query = this.neo4j.initQuery();
|
|
@@ -488,6 +498,27 @@ let OAuthRepository = class OAuthRepository {
|
|
|
488
498
|
// ============================================
|
|
489
499
|
// USER LOOKUP METHODS
|
|
490
500
|
// ============================================
|
|
501
|
+
/**
|
|
502
|
+
* Whether the user a token was issued to may still use it: the user exists,
|
|
503
|
+
* is not deleted, is active and, when the token carries a company, still
|
|
504
|
+
* BELONGS_TO that company. A token without a company (a platform user with no
|
|
505
|
+
* company) only needs the user checks.
|
|
506
|
+
*/
|
|
507
|
+
async isTokenSubjectAuthorised(params) {
|
|
508
|
+
const query = this.neo4j.initQuery();
|
|
509
|
+
query.queryParams = { ...query.queryParams, userId: params.userId, tokenCompanyId: params.companyId ?? null };
|
|
510
|
+
query.query = `
|
|
511
|
+
MATCH (oauthUser:User {id: $userId})
|
|
512
|
+
WHERE coalesce(oauthUser.isDeleted, false) = false
|
|
513
|
+
AND oauthUser.isActive = true
|
|
514
|
+
AND ($tokenCompanyId IS NULL OR EXISTS {
|
|
515
|
+
MATCH (oauthUser)-[:BELONGS_TO]->(:${company_meta_1.companyMeta.labelName} {id: $tokenCompanyId})
|
|
516
|
+
})
|
|
517
|
+
RETURN count(oauthUser) AS total
|
|
518
|
+
`;
|
|
519
|
+
const total = await this.neo4j.readCount(query.query, query.queryParams);
|
|
520
|
+
return total > 0;
|
|
521
|
+
}
|
|
491
522
|
/**
|
|
492
523
|
* Looks up the company ID for a user.
|
|
493
524
|
* Used to include companyId in OAuth tokens for proper scoping.
|