@generazioneai/authz 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/codegen/authz-check.d.ts +3 -0
  2. package/dist/codegen/authz-check.d.ts.map +1 -0
  3. package/dist/codegen/authz-check.js +76 -0
  4. package/dist/codegen/authz-check.js.map +1 -0
  5. package/dist/codegen/check-rules.d.ts +73 -0
  6. package/dist/codegen/check-rules.d.ts.map +1 -0
  7. package/dist/codegen/check-rules.js +387 -0
  8. package/dist/codegen/check-rules.js.map +1 -0
  9. package/dist/codegen/effective-actions.d.ts +13 -0
  10. package/dist/codegen/effective-actions.d.ts.map +1 -0
  11. package/dist/codegen/effective-actions.js +44 -0
  12. package/dist/codegen/effective-actions.js.map +1 -0
  13. package/dist/codegen/generate-types.d.ts +8 -0
  14. package/dist/codegen/generate-types.d.ts.map +1 -0
  15. package/dist/codegen/generate-types.js +121 -0
  16. package/dist/codegen/generate-types.js.map +1 -0
  17. package/dist/codegen/index.d.ts +3 -0
  18. package/dist/codegen/index.d.ts.map +1 -0
  19. package/dist/codegen/index.js +74 -0
  20. package/dist/codegen/index.js.map +1 -0
  21. package/dist/codegen/manifest-io.d.ts +19 -0
  22. package/dist/codegen/manifest-io.d.ts.map +1 -0
  23. package/dist/codegen/manifest-io.js +59 -0
  24. package/dist/codegen/manifest-io.js.map +1 -0
  25. package/dist/context/als.d.ts +14 -0
  26. package/dist/context/als.d.ts.map +1 -0
  27. package/dist/context/als.js +30 -0
  28. package/dist/context/als.js.map +1 -0
  29. package/dist/context/authz-context.d.ts +54 -0
  30. package/dist/context/authz-context.d.ts.map +1 -0
  31. package/dist/context/authz-context.js +24 -0
  32. package/dist/context/authz-context.js.map +1 -0
  33. package/dist/define-resource.d.ts +150 -0
  34. package/dist/define-resource.d.ts.map +1 -0
  35. package/dist/define-resource.js +26 -0
  36. package/dist/define-resource.js.map +1 -0
  37. package/dist/index.d.ts +7 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +23 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/nats/canonical-hash.d.ts +5 -0
  42. package/dist/nats/canonical-hash.d.ts.map +1 -0
  43. package/dist/nats/canonical-hash.js +24 -0
  44. package/dist/nats/canonical-hash.js.map +1 -0
  45. package/dist/nats/index.d.ts +7 -0
  46. package/dist/nats/index.d.ts.map +1 -0
  47. package/dist/nats/index.js +27 -0
  48. package/dist/nats/index.js.map +1 -0
  49. package/dist/nats/internal-token.d.ts +56 -0
  50. package/dist/nats/internal-token.d.ts.map +1 -0
  51. package/dist/nats/internal-token.js +93 -0
  52. package/dist/nats/internal-token.js.map +1 -0
  53. package/dist/nats/internal-token.signer.d.ts +21 -0
  54. package/dist/nats/internal-token.signer.d.ts.map +1 -0
  55. package/dist/nats/internal-token.signer.js +48 -0
  56. package/dist/nats/internal-token.signer.js.map +1 -0
  57. package/dist/nats/jwks-client.d.ts +10 -0
  58. package/dist/nats/jwks-client.d.ts.map +1 -0
  59. package/dist/nats/jwks-client.js +14 -0
  60. package/dist/nats/jwks-client.js.map +1 -0
  61. package/dist/nats/key-loader.d.ts +24 -0
  62. package/dist/nats/key-loader.d.ts.map +1 -0
  63. package/dist/nats/key-loader.js +65 -0
  64. package/dist/nats/key-loader.js.map +1 -0
  65. package/dist/nats/replay-cache.d.ts +14 -0
  66. package/dist/nats/replay-cache.d.ts.map +1 -0
  67. package/dist/nats/replay-cache.js +23 -0
  68. package/dist/nats/replay-cache.js.map +1 -0
  69. package/dist/nest/authz-context.interceptor.d.ts +6 -0
  70. package/dist/nest/authz-context.interceptor.d.ts.map +1 -0
  71. package/dist/nest/authz-context.interceptor.js +47 -0
  72. package/dist/nest/authz-context.interceptor.js.map +1 -0
  73. package/dist/nest/authz-context.middleware.d.ts +15 -0
  74. package/dist/nest/authz-context.middleware.d.ts.map +1 -0
  75. package/dist/nest/authz-context.middleware.js +40 -0
  76. package/dist/nest/authz-context.middleware.js.map +1 -0
  77. package/dist/nest/index.d.ts +6 -0
  78. package/dist/nest/index.d.ts.map +1 -0
  79. package/dist/nest/index.js +25 -0
  80. package/dist/nest/index.js.map +1 -0
  81. package/dist/nest/internal-auth.interceptor.d.ts +29 -0
  82. package/dist/nest/internal-auth.interceptor.d.ts.map +1 -0
  83. package/dist/nest/internal-auth.interceptor.js +140 -0
  84. package/dist/nest/internal-auth.interceptor.js.map +1 -0
  85. package/dist/nest/nats-scoped-client.proxy.d.ts +23 -0
  86. package/dist/nest/nats-scoped-client.proxy.d.ts.map +1 -0
  87. package/dist/nest/nats-scoped-client.proxy.js +50 -0
  88. package/dist/nest/nats-scoped-client.proxy.js.map +1 -0
  89. package/dist/nest/skip-internal-auth.decorator.d.ts +4 -0
  90. package/dist/nest/skip-internal-auth.decorator.d.ts.map +1 -0
  91. package/dist/nest/skip-internal-auth.decorator.js +13 -0
  92. package/dist/nest/skip-internal-auth.decorator.js.map +1 -0
  93. package/dist/resource-registry.d.ts +31 -0
  94. package/dist/resource-registry.d.ts.map +1 -0
  95. package/dist/resource-registry.js +64 -0
  96. package/dist/resource-registry.js.map +1 -0
  97. package/dist/resource-registry.module.d.ts +25 -0
  98. package/dist/resource-registry.module.d.ts.map +1 -0
  99. package/dist/resource-registry.module.js +67 -0
  100. package/dist/resource-registry.module.js.map +1 -0
  101. package/dist/scope-substitute.d.ts +20 -0
  102. package/dist/scope-substitute.d.ts.map +1 -0
  103. package/dist/scope-substitute.js +58 -0
  104. package/dist/scope-substitute.js.map +1 -0
  105. package/package.json +94 -0
@@ -0,0 +1,8 @@
1
+ import type { ResourceManifest } from '../define-resource';
2
+ export interface GeneratedFile {
3
+ filename: string;
4
+ content: string;
5
+ }
6
+ /** Emit all generated files for `@generazioneai/authz-types/src/generated/`. */
7
+ export declare function generateTypeFiles(manifests: ResourceManifest[]): GeneratedFile[];
8
+ //# sourceMappingURL=generate-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-types.d.ts","sourceRoot":"","sources":["../../src/codegen/generate-types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAoHD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,EAAE,GAAG,aAAa,EAAE,CAShF"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ // Step 8 DEC-S8.1: codegen emitters for `@generazioneai/authz-types/src/generated/`.
3
+ //
4
+ // Pure functions: manifests in → file contents out. No filesystem here (the CLI
5
+ // in `index.ts` does the IO). Output is deterministic (subjects + actions sorted)
6
+ // so `authz:codegen --check` drift detection is stable (DEC-S8.4).
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.generateTypeFiles = generateTypeFiles;
9
+ const effective_actions_1 = require("./effective-actions");
10
+ const HEADER = '// @generated by `authz:codegen` — DO NOT EDIT.\n' +
11
+ '// Run `npm run authz:codegen` to regenerate from the resource manifests.\n';
12
+ function sorted(manifests) {
13
+ return [...manifests].sort((a, b) => a.subject.localeCompare(b.subject));
14
+ }
15
+ function genSubjects(manifests) {
16
+ const members = [...sorted(manifests).map((m) => m.subject), 'all'];
17
+ const body = members.map((s) => ` | '${s}'`).join('\n');
18
+ return `${HEADER}\nexport type Subject =\n${body};\n`;
19
+ }
20
+ function genActions(manifests) {
21
+ const entries = sorted(manifests).map((m) => {
22
+ const acts = (0, effective_actions_1.effectiveActions)(m);
23
+ const union = acts.length ? acts.map((a) => `'${a}'`).join(' | ') : 'never';
24
+ return ` ${m.subject}: ${union};`;
25
+ });
26
+ // 'all' is the CASL wildcard subject (system tier `manage`) — any action.
27
+ entries.push(' all: string;');
28
+ return (`${HEADER}\nimport type { Subject } from './subjects';\n\n` +
29
+ '/** Effective actions per subject (declared actions ∪ lifecycle transition verbs). */\n' +
30
+ `export interface SubjectActionMap {\n${entries.join('\n')}\n}\n\n` +
31
+ 'export type ActionFor<S extends Subject> = SubjectActionMap[S];\n' +
32
+ "/** Union of every concrete action across all subjects (excludes the 'all' wildcard). */\n" +
33
+ "export type Action = SubjectActionMap[Exclude<Subject, 'all'>];\n");
34
+ }
35
+ function genSubjectShapes(manifests) {
36
+ const mapBody = sorted(manifests)
37
+ .map((m) => ` ${m.subject}: { service: '${m.service}', model: '${m.prismaModel}' },`)
38
+ .join('\n');
39
+ return `${HEADER}
40
+ /** Maps each Subject to its owning service + Prisma model name (Step 3 lookup). */
41
+ export const SUBJECT_MODEL_MAP = {
42
+ ${mapBody}
43
+ } as const;
44
+
45
+ export type SubjectModelMap = typeof SUBJECT_MODEL_MAP;
46
+
47
+ /**
48
+ * Per-service Prisma row types are merged here via declaration merging inside the
49
+ * owning service (the SDK cannot import service Prisma clients):
50
+ *
51
+ * declare module '@generazioneai/authz-types' {
52
+ * interface SubjectShape { Course: import('@prisma-lms/client').Course }
53
+ * }
54
+ */
55
+ export interface SubjectShape {}
56
+ `;
57
+ }
58
+ // Static (depends only on the generated Subject/ActionFor types, not on the
59
+ // manifest list). Emitted as a generated file per DEC-S8.1 so all type surface
60
+ // lives under generated/.
61
+ function genAuthorizeDecorator() {
62
+ return `${HEADER}
63
+ import { SetMetadata, type CustomDecorator } from '@nestjs/common';
64
+ import type { Subject } from './subjects';
65
+ import type { ActionFor } from './actions';
66
+
67
+ /** Reflect metadata key read by the gateway's GlobalAuthzGuard (Step 6). */
68
+ export const AUTHZ_REQUIREMENT_KEY = 'skillera:authz:requirement';
69
+
70
+ export interface AuthzRequirement {
71
+ action: string;
72
+ subject: string;
73
+ }
74
+
75
+ /**
76
+ * Declares the route-level authz requirement for a controller handler.
77
+ * Type-safe: \`action\` must be valid for \`subject\` per its resource manifest.
78
+ *
79
+ * @Authorize('read', 'Planning')
80
+ * @Get('plannings')
81
+ * findAll() { ... }
82
+ */
83
+ export function Authorize<S extends Subject>(
84
+ action: ActionFor<S>,
85
+ subject: S,
86
+ ): CustomDecorator {
87
+ return SetMetadata(AUTHZ_REQUIREMENT_KEY, { action, subject } as AuthzRequirement);
88
+ }
89
+ `;
90
+ }
91
+ // DEC-S8.18: perms come from the canonical skillID seed (not the manifests),
92
+ // which does not exist yet — emit a typed placeholder.
93
+ function genPerms() {
94
+ return `${HEADER}
95
+ // Permission slugs are generated from the skillID canonical seed (DEC-S8.18),
96
+ // which does not exist yet. Re-run \`authz:codegen --include-perms\` once it lands.
97
+ export const PERM = {} as const;
98
+ export type PermKey = keyof typeof PERM;
99
+ `;
100
+ }
101
+ function genBarrel() {
102
+ return `${HEADER}
103
+ export * from './subjects';
104
+ export * from './actions';
105
+ export * from './subject-shapes';
106
+ export * from './authorize-decorator';
107
+ export * from './perms';
108
+ `;
109
+ }
110
+ /** Emit all generated files for `@generazioneai/authz-types/src/generated/`. */
111
+ function generateTypeFiles(manifests) {
112
+ return [
113
+ { filename: 'subjects.ts', content: genSubjects(manifests) },
114
+ { filename: 'actions.ts', content: genActions(manifests) },
115
+ { filename: 'subject-shapes.ts', content: genSubjectShapes(manifests) },
116
+ { filename: 'authorize-decorator.ts', content: genAuthorizeDecorator() },
117
+ { filename: 'perms.ts', content: genPerms() },
118
+ { filename: 'index.ts', content: genBarrel() },
119
+ ];
120
+ }
121
+ //# sourceMappingURL=generate-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-types.js","sourceRoot":"","sources":["../../src/codegen/generate-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function runCodegen(argv: string[]): number;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":";AAkDA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAiCjD"}
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // Step 8 DEC-S8.1/3/4: `authz:codegen` CLI.
4
+ //
5
+ // Reads serialized resource manifests (one or more `authz-manifest.json` files)
6
+ // and emits the typed surface into `@generazioneai/authz-types/src/generated/`.
7
+ //
8
+ // Usage:
9
+ // authz:codegen [--manifests <a.json> <b.json>...] [--out <dir>] [--check]
10
+ //
11
+ // `--check` (DEC-S8.4): generate in memory, compare to the checked-in files, exit
12
+ // 1 with a diff list if they differ — the drift gate used in CI.
13
+ //
14
+ // With no `--manifests`, emits the empty baseline (Subject = 'all' only), which is
15
+ // what bootstraps the package before any service ships its manifests.
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.runCodegen = runCodegen;
18
+ const node_fs_1 = require("node:fs");
19
+ const node_path_1 = require("node:path");
20
+ const generate_types_1 = require("./generate-types");
21
+ const manifest_io_1 = require("./manifest-io");
22
+ // Default: resolve `<repo>/packages/authz-types/src/generated` relative to this
23
+ // file (works from dist/codegen/ at runtime and src/codegen/ under ts-node).
24
+ const DEFAULT_OUT = (0, node_path_1.resolve)(__dirname, '../../../authz-types/src/generated');
25
+ function parseArgs(argv) {
26
+ const args = { manifests: [], out: DEFAULT_OUT, check: false };
27
+ for (let i = 0; i < argv.length; i++) {
28
+ const a = argv[i];
29
+ if (a === '--check')
30
+ args.check = true;
31
+ else if (a === '--out')
32
+ args.out = (0, node_path_1.resolve)(argv[++i]);
33
+ else if (a === '--manifests') {
34
+ while (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
35
+ args.manifests.push((0, node_path_1.resolve)(argv[++i]));
36
+ }
37
+ }
38
+ }
39
+ return args;
40
+ }
41
+ function runCodegen(argv) {
42
+ const args = parseArgs(argv);
43
+ const manifests = args.manifests.length ? (0, manifest_io_1.loadManifests)(args.manifests) : [];
44
+ const files = (0, generate_types_1.generateTypeFiles)(manifests);
45
+ if (args.check) {
46
+ const drifted = [];
47
+ for (const f of files) {
48
+ const path = (0, node_path_1.join)(args.out, f.filename);
49
+ const current = (0, node_fs_1.existsSync)(path) ? (0, node_fs_1.readFileSync)(path, 'utf8') : null;
50
+ if (current !== f.content)
51
+ drifted.push(f.filename);
52
+ }
53
+ if (drifted.length) {
54
+ console.error(`[authz:codegen] DRIFT — ${drifted.length} generated file(s) out of date: ${drifted.join(', ')}`);
55
+ console.error('[authz:codegen] run `npm run authz:codegen` and commit the result.');
56
+ return 1;
57
+ }
58
+ console.log(`[authz:codegen] OK — ${files.length} generated file(s) in sync (${manifests.length} manifest(s)).`);
59
+ return 0;
60
+ }
61
+ (0, node_fs_1.mkdirSync)(args.out, { recursive: true });
62
+ for (const f of files) {
63
+ const path = (0, node_path_1.join)(args.out, f.filename);
64
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true });
65
+ (0, node_fs_1.writeFileSync)(path, f.content, 'utf8');
66
+ }
67
+ console.log(`[authz:codegen] wrote ${files.length} file(s) to ${args.out} (${manifests.length} manifest(s)).`);
68
+ return 0;
69
+ }
70
+ // Executed directly (not imported) → run.
71
+ if (require.main === module) {
72
+ process.exit(runCodegen(process.argv.slice(2)));
73
+ }
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/codegen/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ResourceManifest } from '../define-resource';
2
+ /** A manifest as it survives `JSON.stringify` (no functions, generics erased). */
3
+ export type SerializedManifest = ResourceManifest;
4
+ export declare function loadManifestFile(path: string): SerializedManifest[];
5
+ /** Load + concatenate manifests from several files (no dedup — checks catch dups). */
6
+ export declare function loadManifests(paths: string[]): SerializedManifest[];
7
+ /**
8
+ * Strip the TS-only generics + any non-JSON residue from a manifest set.
9
+ * A JSON round-trip drops `undefined` keys and would throw on a stray function —
10
+ * a guard that scope templates stayed pure JSON (DEC-2).
11
+ */
12
+ export declare function serializeManifests(manifests: ResourceManifest[]): SerializedManifest[];
13
+ /**
14
+ * DEC-18 (SDK side): the per-service `authz:export` build step calls this with
15
+ * its registered manifests to emit `dist/authz-manifest.json`. skillID's
16
+ * aggregator and the CI `authz:check` / `authz:codegen` gates read those files.
17
+ */
18
+ export declare function writeManifestFile(path: string, manifests: ResourceManifest[]): void;
19
+ //# sourceMappingURL=manifest-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-io.d.ts","sourceRoot":"","sources":["../../src/codegen/manifest-io.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,kFAAkF;AAClF,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAElD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAoBnE;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE,CAInE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,GAC5B,kBAAkB,EAAE,CAEtB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,gBAAgB,EAAE,GAC5B,IAAI,CAGN"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ // Step 1 DEC-18 / Step 8 DEC-S8.1: manifest aggregation for codegen + check.
3
+ //
4
+ // Each service emits a serialized `authz-manifest.json` (an array of manifests).
5
+ // Because scope templates are pure JSON with `{ $ctx }` placeholders (DEC-2),
6
+ // a manifest is fully serializable — the only erased part is the TS-only `W`
7
+ // generic. The codegen / check tooling reads these JSON files and merges them.
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.loadManifestFile = loadManifestFile;
10
+ exports.loadManifests = loadManifests;
11
+ exports.serializeManifests = serializeManifests;
12
+ exports.writeManifestFile = writeManifestFile;
13
+ const node_fs_1 = require("node:fs");
14
+ const node_path_1 = require("node:path");
15
+ function loadManifestFile(path) {
16
+ if (!(0, node_fs_1.existsSync)(path)) {
17
+ throw new Error(`[authz] manifest file not found: ${path}`);
18
+ }
19
+ const raw = (0, node_fs_1.readFileSync)(path, 'utf8');
20
+ let parsed;
21
+ try {
22
+ parsed = JSON.parse(raw);
23
+ }
24
+ catch (e) {
25
+ throw new Error(`[authz] invalid JSON in ${path}: ${e.message}`);
26
+ }
27
+ const arr = Array.isArray(parsed)
28
+ ? parsed
29
+ : parsed?.manifests;
30
+ if (!Array.isArray(arr)) {
31
+ throw new Error(`[authz] ${path} must be a JSON array of manifests (or { "manifests": [...] }).`);
32
+ }
33
+ return arr;
34
+ }
35
+ /** Load + concatenate manifests from several files (no dedup — checks catch dups). */
36
+ function loadManifests(paths) {
37
+ const all = [];
38
+ for (const p of paths)
39
+ all.push(...loadManifestFile(p));
40
+ return all;
41
+ }
42
+ /**
43
+ * Strip the TS-only generics + any non-JSON residue from a manifest set.
44
+ * A JSON round-trip drops `undefined` keys and would throw on a stray function —
45
+ * a guard that scope templates stayed pure JSON (DEC-2).
46
+ */
47
+ function serializeManifests(manifests) {
48
+ return JSON.parse(JSON.stringify(manifests));
49
+ }
50
+ /**
51
+ * DEC-18 (SDK side): the per-service `authz:export` build step calls this with
52
+ * its registered manifests to emit `dist/authz-manifest.json`. skillID's
53
+ * aggregator and the CI `authz:check` / `authz:codegen` gates read those files.
54
+ */
55
+ function writeManifestFile(path, manifests) {
56
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true });
57
+ (0, node_fs_1.writeFileSync)(path, JSON.stringify(serializeManifests(manifests), null, 2) + '\n', 'utf8');
58
+ }
59
+ //# sourceMappingURL=manifest-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-io.js","sourceRoot":"","sources":["../../src/codegen/manifest-io.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,EAAE;AACF,iFAAiF;AACjF,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;;AAS/E,4CAoBC;AAGD,sCAIC;AAOD,gDAIC;AAOD,8CAMC;AA1DD,qCAA6E;AAC7E,yCAAoC;AAMpC,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAA,oBAAU,EAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,GAAG,GAAG,IAAA,sBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC,CAAC,MAAM;QACR,CAAC,CAAE,MAAkC,EAAE,SAAS,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,iEAAiE,CACjF,CAAC;IACJ,CAAC;IACD,OAAO,GAA2B,CAAC;AACrC,CAAC;AAED,sFAAsF;AACtF,SAAgB,aAAa,CAAC,KAAe;IAC3C,MAAM,GAAG,GAAyB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAChC,SAA6B;IAE7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,SAAgB,iBAAiB,CAC/B,IAAY,EACZ,SAA6B;IAE7B,IAAA,mBAAS,EAAC,IAAA,mBAAO,EAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAA,uBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7F,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import type { AuthzContext } from './authz-context';
3
+ /**
4
+ * Singleton ALS condivisa. Importata ovunque serva leggere/popolare il context.
5
+ *
6
+ * Esempio popolamento (middleware/guard):
7
+ * authzAls.run(buildAuthzContext(req), () => next());
8
+ *
9
+ * Esempio lettura (repository/extension hook):
10
+ * const ctx = authzAls.getStore();
11
+ * if (!ctx) throw new UnscopedQueryException();
12
+ */
13
+ export declare const authzAls: AsyncLocalStorage<AuthzContext>;
14
+ //# sourceMappingURL=als.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"als.d.ts","sourceRoot":"","sources":["../../src/context/als.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,EAAE,iBAAiB,CAAC,YAAY,CACd,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // Step 2 DEC-S2.17/24: AsyncLocalStorage condivisa tra gateway e downstream.
3
+ // Pattern allineato a skillAuth/src/oidc/common/request-context.ts (esistente).
4
+ //
5
+ // Popolata:
6
+ // - Gateway: `AuthzContextMiddleware` post-JwtAuthGuard+TenantGuard, prima dei controller
7
+ // - Downstream (skillID/skillCertet): `InternalAuthGuard` post-verify JWT firmato (Step 6 DEC-S6.3)
8
+ // legge `snap` ref dal JWT, fetcha snapshot da Redis, popola contesto, runs handler dentro als.run().
9
+ //
10
+ // Letta:
11
+ // - ScopedRepository (Step 3)
12
+ // - Prisma extension hook $allOperations (Step 3 DEC-S3.6)
13
+ // - SecureQueryEngine (Step 5)
14
+ // - GlobalAuthzGuard (Step 6)
15
+ // - AuditEmitter (Step 7, quando attivato)
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.authzAls = void 0;
18
+ const node_async_hooks_1 = require("node:async_hooks");
19
+ /**
20
+ * Singleton ALS condivisa. Importata ovunque serva leggere/popolare il context.
21
+ *
22
+ * Esempio popolamento (middleware/guard):
23
+ * authzAls.run(buildAuthzContext(req), () => next());
24
+ *
25
+ * Esempio lettura (repository/extension hook):
26
+ * const ctx = authzAls.getStore();
27
+ * if (!ctx) throw new UnscopedQueryException();
28
+ */
29
+ exports.authzAls = new node_async_hooks_1.AsyncLocalStorage();
30
+ //# sourceMappingURL=als.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"als.js","sourceRoot":"","sources":["../../src/context/als.ts"],"names":[],"mappings":";AAAA,6EAA6E;AAC7E,gFAAgF;AAChF,EAAE;AACF,YAAY;AACZ,4FAA4F;AAC5F,sGAAsG;AACtG,0GAA0G;AAC1G,EAAE;AACF,SAAS;AACT,gCAAgC;AAChC,6DAA6D;AAC7D,iCAAiC;AACjC,gCAAgC;AAChC,6CAA6C;;;AAE7C,uDAAqD;AAGrD;;;;;;;;;GASG;AACU,QAAA,QAAQ,GACnB,IAAI,oCAAiB,EAAgB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import type { PrismaAbility } from '@casl/prisma';
2
+ /**
3
+ * Path validi nei template `$ctx` dei resource manifest (Step 1).
4
+ * Usato come union literal per type-check compile-time dei manifest.
5
+ * Estendibile via codegen quando si aggiungono campi al context.
6
+ */
7
+ export type CtxPath = 'userId' | 'individualId' | 'tenantId' | 'juridicalIndividualId' | `connected.${'studentsOfTeacher' | 'reportsOfManager' | 'pendingApprovalResourceIds' | 'customRelations'}` | `accreditedAs.${'provider' | 'customer'}.${'accreditationIds' | 'customerJuridicalIds' | 'providerJuridicalIds'}` | string;
8
+ export interface ConnectedEdges {
9
+ studentsOfTeacher: string[];
10
+ reportsOfManager: string[];
11
+ pendingApprovalResourceIds: Record<string, string[]>;
12
+ customRelations?: Record<string, string[]>;
13
+ }
14
+ export interface AccreditedAs {
15
+ provider: {
16
+ accreditationIds: string[];
17
+ customerJuridicalIds: string[];
18
+ };
19
+ customer: {
20
+ accreditationIds: string[];
21
+ providerJuridicalIds: string[];
22
+ };
23
+ }
24
+ /**
25
+ * Contesto authz per una request. Vive in AsyncLocalStorage.
26
+ * Letto da: ScopedRepository, Prisma extension hook, GenQuery v2, GlobalAuthzGuard.
27
+ */
28
+ export interface AuthzContext {
29
+ userId: string;
30
+ individualId?: string;
31
+ tenantId?: string;
32
+ juridicalIndividualId?: string;
33
+ /** Pre-calcolato da skillID nello snapshot builder (Step 4) */
34
+ connected: ConnectedEdges;
35
+ accreditedAs: AccreditedAs;
36
+ /** PrismaAbility hidratata da `createPrismaAbility(snapshot.rules)` */
37
+ ability: PrismaAbility<any>;
38
+ /** Snapshot identifier (Step 4) — propagato nei JWT NATS (Step 2 claim `snap`) */
39
+ snapId?: string;
40
+ /** Hash truncated 32 hex char (Step 4 DEC-S4.9) — JWT claim `ph` per sanity check */
41
+ permHash?: string;
42
+ /** Flag impostata da `runUnscoped()` (Step 3 DEC-S3.17). Hook check bypassa scope se true. */
43
+ unscoped?: boolean;
44
+ unscopedReason?: string;
45
+ /** Override action per lifecycle transition (Step 3 DEC-S3.15) */
46
+ actionOverride?: string;
47
+ /** Cache per-request `accessibleBy(ability, action)[subject]` (Step 3 DEC-S3.25) */
48
+ accessibleByCache?: Map<string, unknown>;
49
+ /** Modalità soft-delete (Step 3 DEC-S3.11): default null, opt-in 'include-deleted'/'only-deleted' */
50
+ softDeleteMode?: 'normal' | 'include-deleted' | 'only-deleted';
51
+ }
52
+ /** Context vuoto usato come baseline da `runUnscoped()` quando non c'è parent context. */
53
+ export declare const EMPTY_CTX: AuthzContext;
54
+ //# sourceMappingURL=authz-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authz-context.d.ts","sourceRoot":"","sources":["../../src/context/authz-context.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,OAAO,GACf,QAAQ,GACR,cAAc,GACd,UAAU,GACV,uBAAuB,GACvB,aACI,mBAAmB,GACnB,kBAAkB,GAClB,4BAA4B,GAC5B,iBAAiB,EAAE,GACvB,gBAAgB,UAAU,GAAG,UAAU,IACnC,kBAAkB,GAClB,sBAAsB,GACtB,sBAAsB,EAAE,GAC5B,MAAM,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE;QACR,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;KAChC,CAAC;IACF,QAAQ,EAAE;QACR,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;KAChC,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,+DAA+D;IAC/D,SAAS,EAAE,cAAc,CAAC;IAC1B,YAAY,EAAE,YAAY,CAAC;IAE3B,uEAAuE;IACvE,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAE5B,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEzC,qGAAqG;IACrG,cAAc,CAAC,EAAE,QAAQ,GAAG,iBAAiB,GAAG,cAAc,CAAC;CAChE;AAED,0FAA0F;AAC1F,eAAO,MAAM,SAAS,EAAE,YAcvB,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // Step 2 DEC-S2.17 / Step 4 DEC-S4.1
3
+ // AuthzContext: il payload che vive in ALS per ogni request.
4
+ // Popolato dal middleware al gateway (post-snapshot-fetch) e dal verifier al downstream
5
+ // (post-JWT-verify + post-snapshot-fetch-via-snapId).
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EMPTY_CTX = void 0;
8
+ /** Context vuoto usato come baseline da `runUnscoped()` quando non c'è parent context. */
9
+ exports.EMPTY_CTX = {
10
+ userId: '__system__',
11
+ connected: {
12
+ studentsOfTeacher: [],
13
+ reportsOfManager: [],
14
+ pendingApprovalResourceIds: {},
15
+ },
16
+ accreditedAs: {
17
+ provider: { accreditationIds: [], customerJuridicalIds: [] },
18
+ customer: { accreditationIds: [], providerJuridicalIds: [] },
19
+ },
20
+ ability: null,
21
+ unscoped: true,
22
+ unscopedReason: 'system-bootstrap',
23
+ };
24
+ //# sourceMappingURL=authz-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authz-context.js","sourceRoot":"","sources":["../../src/context/authz-context.ts"],"names":[],"mappings":";AAAA,qCAAqC;AACrC,6DAA6D;AAC7D,wFAAwF;AACxF,sDAAsD;;;AA+EtD,0FAA0F;AAC7E,QAAA,SAAS,GAAiB;IACrC,MAAM,EAAE,YAAY;IACpB,SAAS,EAAE;QACT,iBAAiB,EAAE,EAAE;QACrB,gBAAgB,EAAE,EAAE;QACpB,0BAA0B,EAAE,EAAE;KAC/B;IACD,YAAY,EAAE;QACZ,QAAQ,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE;QAC5D,QAAQ,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE;KAC7D;IACD,OAAO,EAAE,IAAqC;IAC9C,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,kBAAkB;CACnC,CAAC"}
@@ -0,0 +1,150 @@
1
+ import type { CtxPath } from './context/authz-context';
2
+ /** Placeholder $ctx nei template scope. Sostituito a build-time snapshot dal builder skillID. */
3
+ export type CtxPlaceholder = {
4
+ $ctx: CtxPath;
5
+ };
6
+ export type DeepPartial<T> = {
7
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
8
+ };
9
+ /**
10
+ * Template Prisma WhereInput con segnaposti `{ $ctx: 'path' }` al posto dei valori.
11
+ * Esempio:
12
+ * { juridicalId: { $ctx: 'tenantId' } }
13
+ * → al snapshot build diventa { juridicalId: '<actual tenantId>' }
14
+ */
15
+ export type WhereTemplate<W> = DeepPartial<W | {
16
+ [k: string]: CtxPlaceholder | any;
17
+ }>;
18
+ /**
19
+ * 5 kind di tenancy (Step 1 DEC-6/7/8/9/10 con scope ristretto):
20
+ * - single: standard `juridicalId` required (es. JuridicalIndividual)
21
+ * - multiRef: N FK juridical OR-uniti (es. Planning, JuridicalAccreditation)
22
+ * - transitive: ereditata via single relation (es. Certificate via IndividualDocument)
23
+ * - inheritFrom: ereditata via relation chain multi-hop (junction, PlanningResult deep)
24
+ * - global: nessuna tenancy (catalog, top-level masters)
25
+ */
26
+ export type TenancyDecl = {
27
+ kind: 'single';
28
+ field: string;
29
+ } | {
30
+ kind: 'multiRef';
31
+ fields: string[];
32
+ relation: 'AND' | 'OR';
33
+ } | {
34
+ kind: 'transitive';
35
+ via: string;
36
+ through: string;
37
+ field: string;
38
+ } | {
39
+ kind: 'inheritFrom';
40
+ relation: string;
41
+ field?: string;
42
+ } | {
43
+ kind: 'global';
44
+ };
45
+ /** Step 1 DEC-11: ownership sempre array, multi-actor distinto per role. */
46
+ export type OwnershipDecl = {
47
+ field: string;
48
+ actor: 'individualId' | 'juridicalIndividualId' | 'userId';
49
+ role?: 'submitter' | 'reviewer' | 'approver' | 'methodologist' | 'releaser' | 'actor';
50
+ };
51
+ /** Step 1 DEC-15/DEC-S3.21: lifecycle state machine inline nel manifest. */
52
+ export type LifecycleDecl<S extends string> = {
53
+ field: string;
54
+ initial: S;
55
+ states: readonly S[];
56
+ transitions: Record<string, {
57
+ from: readonly S[];
58
+ to: S;
59
+ requires?: ('TENANT' | 'OWN' | 'CONNECTED')[];
60
+ }>;
61
+ };
62
+ /** Step 1 DEC-21 + Step 5: autoquery allowlist whitelist tassativa. */
63
+ export type AutoqueryDecl = {
64
+ filterable: Record<string, readonly ('eq' | 'in' | 'contains' | 'gte' | 'lte' | 'gt' | 'lt' | 'between' | 'null')[]>;
65
+ sortable: readonly string[];
66
+ includable: readonly string[];
67
+ pagination: {
68
+ default: number;
69
+ max: number;
70
+ cursorRequiredOver?: number;
71
+ /** Step 5 DEC-S5.10: opt-in per autorizzare paginazione unbounded. Default false. */
72
+ allowUnbounded?: boolean;
73
+ };
74
+ /** Step 5 DEC-S5.31: default sort se client non passa orderBy. Fallback {id:'desc'}. */
75
+ defaultSort?: {
76
+ field: string;
77
+ order: 'asc' | 'desc';
78
+ };
79
+ };
80
+ export type AuditDecl = {
81
+ create?: 'always' | 'never';
82
+ update?: 'always' | 'never' | 'fields';
83
+ delete?: 'always';
84
+ custom?: string[];
85
+ /** Step 7 DEC-S7.7: campi che richiedono PII redaction nei log. */
86
+ piiFields?: string[];
87
+ /** Step 7 EDGE-S7.8: cattura diff before/after nei mutate. Default false. */
88
+ captureDiff?: boolean;
89
+ };
90
+ export interface ResourceManifest<W = any, S extends string = string, ST extends string = string> {
91
+ /** CASL Subject literal — es. 'JuridicalIndividual' */
92
+ subject: S;
93
+ /** Prisma model name camelCase — es. 'juridicalIndividual' */
94
+ prismaModel: string;
95
+ /** Step 1 DEC-5: union literal stretto */
96
+ service: 'skillAuth' | 'skillID' | 'skillCertet';
97
+ tenancy: TenancyDecl;
98
+ ownership?: OwnershipDecl[];
99
+ /** Cross-tenant link (JuridicalAccreditation) — provider/customer field names */
100
+ external?: {
101
+ providerField: string;
102
+ customerField: string;
103
+ };
104
+ /**
105
+ * Step 1 DEC-25a / DEC-S5.16 (codegen): polymorphic dispatch (e.g. ApprovalRequest).
106
+ * Values are OTHER subjects (the target resources), not this resource's own subject,
107
+ * so they are plain subject strings — validated against the registry by `authz:check`.
108
+ */
109
+ polymorphicMap?: Record<string, string>;
110
+ /**
111
+ * Step 1 DEC-12/27: nested children — standalone findMany BLOCKED. `parent`/`rootSubject`
112
+ * reference OTHER subjects (the ancestor resources), hence subject strings (not `S`).
113
+ */
114
+ nested?: {
115
+ parent: string;
116
+ via: string;
117
+ rootSubject?: string;
118
+ };
119
+ /** Step 1 DEC-23: default attivo {field:'deletedAt', restoreAction:'restore'} */
120
+ softDelete?: false | {
121
+ field?: 'deletedAt';
122
+ restoreAction?: string;
123
+ };
124
+ lifecycle?: LifecycleDecl<ST>;
125
+ /** Lista actions consentite. Step 1 DEC-17: lifecycle verbs auto-aggiunti da framework. */
126
+ actions: readonly string[];
127
+ /** Scope templates per i 6 scope CASL. Sostituiti a build-time snapshot. */
128
+ scopes: Partial<Record<'TENANT' | 'OWN' | 'CONNECTED' | 'PROVIDER' | 'CUSTOMER' | 'GLOBAL', WhereTemplate<W>>>;
129
+ autoquery: AutoqueryDecl;
130
+ audit?: AuditDecl;
131
+ documentation?: {
132
+ description: string;
133
+ owner: string;
134
+ };
135
+ }
136
+ /**
137
+ * Identity function generica. Type inference vincola scope templates a essere
138
+ * strutturalmente compatibili con `Prisma.<Model>WhereInput`.
139
+ *
140
+ * Esempio:
141
+ * export const CourseResource = defineResource<Prisma.CourseWhereInput, 'Course'>({
142
+ * subject: 'Course',
143
+ * prismaModel: 'course',
144
+ * service: 'skillID',
145
+ * tenancy: { kind: 'single', field: 'juridicalId' },
146
+ * // ...
147
+ * });
148
+ */
149
+ export declare function defineResource<W = any, S extends string = string, ST extends string = string>(manifest: ResourceManifest<W, S, ST>): ResourceManifest<W, S, ST>;
150
+ //# sourceMappingURL=define-resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-resource.d.ts","sourceRoot":"","sources":["../src/define-resource.ts"],"names":[],"mappings":"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"}