@rhino-dev/rhino-nestjs 4.2.0 → 4.3.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.
@@ -39,6 +39,7 @@ const fs = __importStar(require("fs"));
39
39
  const path = __importStar(require("path"));
40
40
  const blueprint_parser_1 = require("./blueprint-parser");
41
41
  const blueprint_validator_1 = require("./blueprint-validator");
42
+ const blueprint_sorter_1 = require("./blueprint-sorter");
42
43
  const manifest_manager_1 = require("./manifest-manager");
43
44
  const prisma_schema_generator_1 = require("./generators/prisma-schema-generator");
44
45
  const resource_definition_generator_1 = require("./generators/resource-definition-generator");
@@ -95,7 +96,37 @@ class BlueprintRunner {
95
96
  return result;
96
97
  }
97
98
  const manifest = new manifest_manager_1.ManifestManager(manifestDir);
98
- for (const filename of yamlFiles) {
99
+ // Order so a referenced model is processed before any model that
100
+ // foreign-keys to it (parents before children) — keeps order-sensitive
101
+ // output (e.g. seeders) runnable and matches the Laravel/Rails stacks, where
102
+ // migration timestamps follow this order.
103
+ const sorter = new blueprint_sorter_1.BlueprintSorter();
104
+ const parsedForOrder = [];
105
+ const unparseable = [];
106
+ for (const f of yamlFiles) {
107
+ try {
108
+ parsedForOrder.push({ file: f, blueprint: this.parser.parseModel(path.join(blueprintsDir, f)) });
109
+ }
110
+ catch {
111
+ unparseable.push(f);
112
+ }
113
+ }
114
+ const orderedBlueprints = sorter.sort(parsedForOrder.map((p) => p.blueprint));
115
+ const fileByModel = new Map();
116
+ for (const p of parsedForOrder) {
117
+ if (!fileByModel.has(p.blueprint.model)) {
118
+ fileByModel.set(p.blueprint.model, p.file);
119
+ }
120
+ }
121
+ const orderedYamlFiles = [
122
+ ...orderedBlueprints.map((bp) => fileByModel.get(bp.model)).filter(Boolean),
123
+ ...unparseable,
124
+ ];
125
+ if (sorter.cycles.length > 0) {
126
+ this.log(` ⚠ Circular foreign-key dependency among: ${sorter.cycles.join(', ')}. ` +
127
+ 'Order is best-effort — make one side nullable or add the FK in a later step.', options);
128
+ }
129
+ for (const filename of orderedYamlFiles) {
99
130
  const filePath = path.join(blueprintsDir, filename);
100
131
  try {
101
132
  // Parse
@@ -1 +1 @@
1
- {"version":3,"file":"blueprint-runner.js","sourceRoot":"","sources":["../../src/blueprint/blueprint-runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blueprint-runner.js","sourceRoot":"","sources":["../../src/blueprint/blueprint-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Orders blueprints so that a referenced model is processed before any model
3
+ * whose foreign keys point at it (parents before children).
4
+ *
5
+ * Foreign keys are taken from `foreignId` columns that carry a `foreignModel`
6
+ * mapping to another model in the same generation set. References that impose no
7
+ * ordering are ignored:
8
+ * - self-references (a model's FK to its own table),
9
+ * - references to models NOT in this set (e.g. `Organization`/`User`, created
10
+ * by `rhino install`, not the blueprint run).
11
+ *
12
+ * Prisma resolves relations regardless of model declaration order, but the
13
+ * processing order still matters for order-sensitive output (notably seeders: a
14
+ * child row referencing a parent must be inserted after it) and for parity with
15
+ * the Laravel/Rails stacks, where migration timestamps follow this order.
16
+ *
17
+ * Uses Kahn's algorithm with a stable tie-break: among models with no remaining
18
+ * unmet dependency, the one earliest in the input order wins. The input is
19
+ * already alphabetical, so the output stays alphabetical wherever relationships
20
+ * don't force a reorder.
21
+ *
22
+ * A circular FK dependency (A → B → A) has no linear order; such models are
23
+ * emitted in a deterministic best-effort order and reported via {@link cycles}
24
+ * so the caller can warn (one side should be a nullable / deferred FK).
25
+ */
26
+ export interface SortableColumn {
27
+ type?: string;
28
+ foreignModel?: string | null;
29
+ }
30
+ export interface SortableBlueprint {
31
+ model: string;
32
+ columns?: SortableColumn[];
33
+ }
34
+ export declare class BlueprintSorter {
35
+ private _cycles;
36
+ /**
37
+ * Model names involved in a circular foreign-key dependency during the last
38
+ * {@link sort} (empty when the dependency graph is acyclic).
39
+ */
40
+ get cycles(): string[];
41
+ /** Re-order blueprints into a valid sequence (parents first). */
42
+ sort<T extends SortableBlueprint>(blueprints: T[]): T[];
43
+ /**
44
+ * Whether `start` can reach itself by following dependency edges — i.e. it
45
+ * participates in a circular foreign-key dependency. `adj` maps a model to the
46
+ * models that reference it (its dependents).
47
+ */
48
+ private reachableFromSelf;
49
+ /**
50
+ * The model names this blueprint's foreign keys point at, taken from its
51
+ * `foreignId` columns that carry a `foreignModel`.
52
+ */
53
+ private dependencyModels;
54
+ }
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BlueprintSorter = void 0;
4
+ class BlueprintSorter {
5
+ _cycles = [];
6
+ /**
7
+ * Model names involved in a circular foreign-key dependency during the last
8
+ * {@link sort} (empty when the dependency graph is acyclic).
9
+ */
10
+ get cycles() {
11
+ return this._cycles;
12
+ }
13
+ /** Re-order blueprints into a valid sequence (parents first). */
14
+ sort(blueprints) {
15
+ this._cycles = [];
16
+ if (blueprints.length < 2) {
17
+ return [...blueprints];
18
+ }
19
+ const byModel = new Map();
20
+ for (const bp of blueprints) {
21
+ if (bp.model && !byModel.has(bp.model)) {
22
+ byModel.set(bp.model, bp);
23
+ }
24
+ }
25
+ const dependents = new Map();
26
+ const indegree = new Map();
27
+ for (const m of byModel.keys()) {
28
+ dependents.set(m, []);
29
+ indegree.set(m, 0);
30
+ }
31
+ for (const [model, bp] of byModel) {
32
+ const seen = new Set();
33
+ for (const ref of this.dependencyModels(bp)) {
34
+ if (ref === model || !byModel.has(ref) || seen.has(ref)) {
35
+ continue;
36
+ }
37
+ seen.add(ref);
38
+ dependents.get(ref).push(model);
39
+ indegree.set(model, (indegree.get(model) ?? 0) + 1);
40
+ }
41
+ }
42
+ const inputOrder = [...byModel.keys()];
43
+ // Record the models that actually participate in a cycle (reachable from
44
+ // themselves), in input order, so the caller can warn about the full cycle.
45
+ for (const model of inputOrder) {
46
+ if (this.reachableFromSelf(model, dependents)) {
47
+ this._cycles.push(model);
48
+ }
49
+ }
50
+ const ordered = [];
51
+ const resolved = new Set();
52
+ while (ordered.length < byModel.size) {
53
+ // Earliest-input model with all dependencies already emitted...
54
+ let pick = inputOrder.find((m) => !resolved.has(m) && indegree.get(m) === 0);
55
+ // ...or, when a cycle blocks the graph, the earliest unresolved model
56
+ // (deterministic cycle-break; the cycle itself is reported via cycles).
57
+ if (pick === undefined) {
58
+ pick = inputOrder.find((m) => !resolved.has(m));
59
+ }
60
+ const picked = pick;
61
+ ordered.push(byModel.get(picked));
62
+ resolved.add(picked);
63
+ for (const child of dependents.get(picked)) {
64
+ indegree.set(child, (indegree.get(child) ?? 0) - 1);
65
+ }
66
+ }
67
+ return ordered;
68
+ }
69
+ /**
70
+ * Whether `start` can reach itself by following dependency edges — i.e. it
71
+ * participates in a circular foreign-key dependency. `adj` maps a model to the
72
+ * models that reference it (its dependents).
73
+ */
74
+ reachableFromSelf(start, adj) {
75
+ const stack = [...(adj.get(start) ?? [])];
76
+ const visited = new Set();
77
+ while (stack.length > 0) {
78
+ const node = stack.pop();
79
+ if (node === start) {
80
+ return true;
81
+ }
82
+ if (visited.has(node)) {
83
+ continue;
84
+ }
85
+ visited.add(node);
86
+ for (const next of adj.get(node) ?? []) {
87
+ stack.push(next);
88
+ }
89
+ }
90
+ return false;
91
+ }
92
+ /**
93
+ * The model names this blueprint's foreign keys point at, taken from its
94
+ * `foreignId` columns that carry a `foreignModel`.
95
+ */
96
+ dependencyModels(bp) {
97
+ const refs = [];
98
+ for (const col of bp.columns ?? []) {
99
+ if (col.type === 'foreignId' && col.foreignModel) {
100
+ refs.push(col.foreignModel);
101
+ }
102
+ }
103
+ return refs;
104
+ }
105
+ }
106
+ exports.BlueprintSorter = BlueprintSorter;
107
+ //# sourceMappingURL=blueprint-sorter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blueprint-sorter.js","sourceRoot":"","sources":["../../src/blueprint/blueprint-sorter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `npx rhino permissions-migrate [--apply]`
3
+ *
4
+ * Lifts per-user `userRoles.permissions` into the shared `orgRolePermission`
5
+ * role layer, reducing each user row to its delta. Dry-run unless `--apply`.
6
+ *
7
+ * Loads the consumer app's PrismaClient at runtime (the lib has no DB of its
8
+ * own). A custom client can be injected for testing.
9
+ */
10
+ export declare function runPermissionsMigrate(flags: Record<string, string | true>, deps?: {
11
+ loadPrisma?: () => any;
12
+ log?: (msg: string) => void;
13
+ }): Promise<void>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runPermissionsMigrate = runPermissionsMigrate;
4
+ const permissions_migrator_1 = require("../permissions-migrator");
5
+ /**
6
+ * `npx rhino permissions-migrate [--apply]`
7
+ *
8
+ * Lifts per-user `userRoles.permissions` into the shared `orgRolePermission`
9
+ * role layer, reducing each user row to its delta. Dry-run unless `--apply`.
10
+ *
11
+ * Loads the consumer app's PrismaClient at runtime (the lib has no DB of its
12
+ * own). A custom client can be injected for testing.
13
+ */
14
+ async function runPermissionsMigrate(flags, deps = {}) {
15
+ const apply = flags.apply === true || flags.apply === 'true';
16
+ const log = deps.log ?? ((m) => console.log(m));
17
+ let prisma;
18
+ try {
19
+ const load = deps.loadPrisma ??
20
+ (() => {
21
+ // Resolved from the consumer app's installed @prisma/client.
22
+ const { PrismaClient } = require('@prisma/client');
23
+ return new PrismaClient();
24
+ });
25
+ prisma = load();
26
+ }
27
+ catch {
28
+ log('Could not load @prisma/client. Run this from your application root where Prisma is installed.');
29
+ return;
30
+ }
31
+ try {
32
+ const result = await (0, permissions_migrator_1.migratePermissions)(prisma, { apply });
33
+ for (const line of result.lines)
34
+ log(line);
35
+ const verb = apply ? 'Migrated' : 'Would migrate';
36
+ let summary = `${verb} ${result.groupsMigrated} (org, role) group(s); ${result.rowsReduced} user row(s) reduced to deltas.`;
37
+ if (result.skippedExisting > 0) {
38
+ summary += ` Skipped ${result.skippedExisting} group(s) with an existing role layer.`;
39
+ }
40
+ log(summary);
41
+ if (!apply && result.groupsMigrated > 0) {
42
+ log('Dry-run only. Re-run with --apply to write these changes.');
43
+ }
44
+ }
45
+ finally {
46
+ if (typeof prisma.$disconnect === 'function') {
47
+ await prisma.$disconnect().catch(() => undefined);
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=permissions-migrate.command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-migrate.command.js","sourceRoot":"","sources":["../../../src/cli/commands/permissions-migrate.command.ts"],"names":[],"mappings":";;AAWA,sDAyCC;AApDD,kEAA6D;AAE7D;;;;;;;;GAQG;AACI,KAAK,UAAU,qBAAqB,CACzC,KAAoC,EACpC,OAAgE,EAAE;IAElE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAExD,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,IAAI,GACR,IAAI,CAAC,UAAU;YACf,CAAC,GAAG,EAAE;gBACJ,6DAA6D;gBAC7D,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACnD,OAAO,IAAI,YAAY,EAAE,CAAC;YAC5B,CAAC,CAAC,CAAC;QACL,MAAM,GAAG,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,+FAA+F,CAAC,CAAC;QACrG,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC;QAClD,IAAI,OAAO,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,cAAc,0BAA0B,MAAM,CAAC,WAAW,iCAAiC,CAAC;QAC5H,IAAI,MAAM,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,YAAY,MAAM,CAAC,eAAe,wCAAwC,CAAC;QACxF,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,CAAC;QAEb,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YACxC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;AACH,CAAC"}
package/dist/cli/index.js CHANGED
@@ -20,6 +20,7 @@ const generate_command_1 = require("./commands/generate.command");
20
20
  const blueprint_command_1 = require("./commands/blueprint.command");
21
21
  const export_postman_command_1 = require("./commands/export-postman.command");
22
22
  const export_types_command_1 = require("./commands/export-types.command");
23
+ const permissions_migrate_command_1 = require("./commands/permissions-migrate.command");
23
24
  // -----------------------------------------------------------------------
24
25
  // Flag parsing helpers
25
26
  // -----------------------------------------------------------------------
@@ -57,6 +58,7 @@ function printHelp() {
57
58
  blueprint Generate code from YAML blueprints
58
59
  export-postman Export a Postman collection
59
60
  export-types Export TypeScript type definitions
61
+ permissions-migrate Lift per-user permissions into the org role layer (--apply)
60
62
 
61
63
  Options (by command):
62
64
  blueprint
@@ -103,6 +105,9 @@ async function main(argv = process.argv.slice(2)) {
103
105
  output: typeof flags['output'] === 'string' ? flags['output'] : undefined,
104
106
  });
105
107
  break;
108
+ case 'permissions-migrate':
109
+ await (0, permissions_migrate_command_1.runPermissionsMigrate)(flags);
110
+ break;
106
111
  default:
107
112
  printHelp();
108
113
  if (command !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Lift per-user permissions into the shared org role layer.
3
+ *
4
+ * For each (organization, role) group, the literal intersection of every user's
5
+ * `userRoles.permissions` becomes the `orgRolePermission` row (the shared role
6
+ * layer). Each user's row is then reduced to only its delta
7
+ * (`grantedPermissions = permissions − roleLayer`) and its legacy `permissions`
8
+ * is cleared. Effective permissions are preserved exactly (the intersection is a
9
+ * subset of every user's set, so nothing is gained or lost).
10
+ *
11
+ * Safe & idempotent:
12
+ * - Dry-run by default; pass { apply: true } to write.
13
+ * - Groups that already have an orgRolePermission row are skipped.
14
+ * - After a run the legacy permissions are empty, so a second run is a no-op.
15
+ * - Non-tenant (null organization) rows are left untouched.
16
+ *
17
+ * The `prisma` argument is any object exposing the `userRole` and
18
+ * `orgRolePermission` delegates (a real PrismaClient, or a fake in tests).
19
+ */
20
+ export interface MigratePermissionsResult {
21
+ groupsMigrated: number;
22
+ rowsReduced: number;
23
+ skippedExisting: number;
24
+ lines: string[];
25
+ }
26
+ export declare function migratePermissions(prisma: any, { apply }?: {
27
+ apply?: boolean;
28
+ }): Promise<MigratePermissionsResult>;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migratePermissions = migratePermissions;
4
+ function decode(value) {
5
+ if (Array.isArray(value))
6
+ return value.filter((v) => typeof v === 'string');
7
+ if (typeof value === 'string' && value.trim() !== '') {
8
+ try {
9
+ const parsed = JSON.parse(value);
10
+ return Array.isArray(parsed) ? parsed.filter((v) => typeof v === 'string') : [];
11
+ }
12
+ catch {
13
+ return [];
14
+ }
15
+ }
16
+ return [];
17
+ }
18
+ function readOrgId(r) {
19
+ return r.organizationId ?? r.organization_id;
20
+ }
21
+ function readRoleId(r) {
22
+ return r.roleId ?? r.role_id;
23
+ }
24
+ async function migratePermissions(prisma, { apply = false } = {}) {
25
+ const userRoles = await prisma.userRole.findMany();
26
+ const relevant = userRoles.filter((r) => readOrgId(r) != null && readRoleId(r) != null);
27
+ const groups = new Map();
28
+ for (const r of relevant) {
29
+ const key = `${readOrgId(r)}::${readRoleId(r)}`;
30
+ const bucket = groups.get(key);
31
+ if (bucket)
32
+ bucket.push(r);
33
+ else
34
+ groups.set(key, [r]);
35
+ }
36
+ let groupsMigrated = 0;
37
+ let rowsReduced = 0;
38
+ let skippedExisting = 0;
39
+ const lines = [];
40
+ for (const rows of groups.values()) {
41
+ const withLegacy = rows.filter((r) => decode(r.permissions).length > 0);
42
+ if (withLegacy.length === 0)
43
+ continue;
44
+ const orgId = readOrgId(rows[0]);
45
+ const roleId = readRoleId(rows[0]);
46
+ const existing = await prisma.orgRolePermission.findFirst({
47
+ where: { organizationId: orgId, roleId: roleId },
48
+ });
49
+ if (existing) {
50
+ skippedExisting++;
51
+ continue;
52
+ }
53
+ const sets = withLegacy.map((r) => decode(r.permissions));
54
+ const roleLayer = sets.reduce((acc, set) => acc.filter((p) => set.includes(p)));
55
+ lines.push(`org=${orgId} role=${roleId} → role layer [${roleLayer.join(', ')}] (${withLegacy.length} user rows)`);
56
+ if (apply) {
57
+ await prisma.orgRolePermission.create({
58
+ data: { organizationId: orgId, roleId: roleId, permissions: roleLayer },
59
+ });
60
+ for (const r of withLegacy) {
61
+ const legacy = decode(r.permissions);
62
+ const grants = decode(r.grantedPermissions ?? r.granted_permissions);
63
+ const delta = Array.from(new Set([...legacy.filter((p) => !roleLayer.includes(p)), ...grants]));
64
+ await prisma.userRole.update({
65
+ where: { id: r.id },
66
+ data: { permissions: [], grantedPermissions: delta },
67
+ });
68
+ }
69
+ }
70
+ groupsMigrated++;
71
+ rowsReduced += withLegacy.length;
72
+ }
73
+ return { groupsMigrated, rowsReduced, skippedExisting, lines };
74
+ }
75
+ //# sourceMappingURL=permissions-migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-migrator.js","sourceRoot":"","sources":["../../src/cli/permissions-migrator.ts"],"names":[],"mappings":"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"}
@@ -56,8 +56,11 @@ let GroupMembershipGuard = class GroupMembershipGuard {
56
56
  if (rows.length === 0) {
57
57
  throw rhino_exception_1.RhinoException.membershipDenied();
58
58
  }
59
- // Switch the permission source to the matched membership row(s).
59
+ // Switch the permission source to the matched membership row(s). Both the
60
+ // allow set (legacy ∪ granted ∪ role layer) and the deny set come from the
61
+ // matched rows only; deny wins downstream in `userHasPermission`.
60
62
  user.__membershipPermissions = this.membership.permissionsFromRows(rows);
63
+ user.__membershipDeniedPermissions = this.membership.deniedFromRows(rows);
61
64
  return true;
62
65
  }
63
66
  };
@@ -1 +1 @@
1
- {"version":3,"file":"group-membership.guard.js","sourceRoot":"","sources":["../../src/guards/group-membership.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,kDAAqD;AACrD,uEAAmE;AACnE,+DAA2D;AAG3D;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IAFnB,YACmB,MAA0B,EAC1B,UAA6B;QAD7B,WAAM,GAAN,MAAM,CAAoB;QAC1B,eAAU,GAAV,UAAU,CAAmB;IAC7C,CAAC;IAEJ,WAAW,CAAC,OAAyB;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;YAAE,OAAO,IAAI,CAAC;QAE5C,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC,iDAAiD;QAEzE,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QAC5C,0DAA0D;QAC1D,IAAI,UAAU,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,gCAAc,CAAC,gBAAgB,EAAE,CAAC;QAC1C,CAAC;QAED,iEAAiE;QAChE,IAAY,CAAC,uBAAuB,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA9BY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAGgB,iCAAkB;QACd,sCAAiB;GAHrC,oBAAoB,CA8BhC"}
1
+ {"version":3,"file":"group-membership.guard.js","sourceRoot":"","sources":["../../src/guards/group-membership.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,kDAAqD;AACrD,uEAAmE;AACnE,+DAA2D;AAG3D;;;;;;;;;;;;;;;GAeG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IAFnB,YACmB,MAA0B,EAC1B,UAA6B;QAD7B,WAAM,GAAN,MAAM,CAAoB;QAC1B,eAAU,GAAV,UAAU,CAAmB;IAC7C,CAAC;IAEJ,WAAW,CAAC,OAAyB;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;YAAE,OAAO,IAAI,CAAC;QAE5C,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,CAAC,iDAAiD;QAEzE,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QAC5C,0DAA0D;QAC1D,IAAI,UAAU,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEzC,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,gCAAc,CAAC,gBAAgB,EAAE,CAAC;QAC1C,CAAC;QAED,0EAA0E;QAC1E,2EAA2E;QAC3E,kEAAkE;QACjE,IAAY,CAAC,uBAAuB,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACjF,IAAY,CAAC,6BAA6B,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AAjCY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAGgB,iCAAkB;QACd,sCAAiB;GAHrC,oBAAoB,CAiChC"}
@@ -52,12 +52,27 @@ let JwtAuthGuard = class JwtAuthGuard {
52
52
  // behavior is byte-for-byte unchanged.
53
53
  let user = null;
54
54
  if (this.config.multiTenantEnabled()) {
55
+ // Preferred: also eager-load the org role layer (org_role_permissions) so
56
+ // layered permission resolution has the role-level grants. Apps that have
57
+ // not added the OrgRolePermission relation will throw on this include —
58
+ // fall back to the role-only include (grant/deny columns are scalars and
59
+ // still load there), then to a plain lookup. Existing behavior is unchanged.
55
60
  user = await delegate
56
61
  .findUnique({
57
62
  where: { id: payload.sub },
58
- include: { userRoles: { include: { role: true } } },
63
+ include: {
64
+ userRoles: { include: { role: { include: { orgRolePermissions: true } } } },
65
+ },
59
66
  })
60
67
  .catch(() => null);
68
+ if (!user) {
69
+ user = await delegate
70
+ .findUnique({
71
+ where: { id: payload.sub },
72
+ include: { userRoles: { include: { role: true } } },
73
+ })
74
+ .catch(() => null);
75
+ }
61
76
  }
62
77
  if (!user) {
63
78
  user = await delegate
@@ -1 +1 @@
1
- {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAIwB;AACxB,2DAAuD;AACvD,6DAAyD;AACzD,kDAAqD;AACrD,+DAA2D;AAG3D;;;;GAIG;AAEI,IAAM,YAAY,GAAlB,MAAM,YAAY;IAEJ;IACA;IACA;IAHnB,YACmB,IAAiB,EACjB,MAAqB,EACrB,MAA0B;QAF1B,SAAI,GAAJ,IAAI,CAAa;QACjB,WAAM,GAAN,MAAM,CAAe;QACrB,WAAM,GAAN,MAAM,CAAoB;IAC1C,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAgB,CAAC;QAC9D,IAAI,GAAG,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,gCAAc,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,MAAM,gCAAc,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC9C,gEAAgE;QAChE,4EAA4E;QAC5E,yEAAyE;QACzE,wEAAwE;QACxE,6EAA6E;QAC7E,uCAAuC;QACvC,IAAI,IAAI,GAAQ,IAAI,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,MAAM,QAAQ;iBAClB,UAAU,CAAC;gBACV,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE;gBAC1B,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE;aACpD,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,MAAM,QAAQ;iBAClB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;iBAC1C,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,IAAI;YAAE,MAAM,gCAAc,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;QAC/D,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA7CY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAGc,0BAAW;QACT,8BAAa;QACb,iCAAkB;GAJlC,YAAY,CA6CxB"}
1
+ {"version":3,"file":"jwt-auth.guard.js","sourceRoot":"","sources":["../../src/guards/jwt-auth.guard.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export interface MembershipRow {
8
8
  routeGroup: string | null;
9
9
  organizationId: number | string | null;
10
10
  permissions: unknown;
11
+ grantedPermissions?: unknown;
12
+ deniedPermissions?: unknown;
11
13
  role?: any;
12
14
  }
13
15
  /**
@@ -49,8 +51,14 @@ export declare class MembershipService {
49
51
  id: number | string;
50
52
  } | null | undefined, isTenant: boolean): boolean;
51
53
  /**
52
- * Permissions granted to the user from the matched membership rows only
54
+ * ALLOW permissions resolved from the matched membership rows only
53
55
  * (design §6: "permissions then resolve from that matching membership row").
56
+ * Layered: each row contributes legacy ∪ granted ∪ org role layer.
54
57
  */
55
58
  permissionsFromRows(rows: MembershipRow[]): string[];
59
+ /**
60
+ * DENY permissions resolved from the matched membership rows. Deny always
61
+ * wins over the allow set ({@link permissionsFromRows}).
62
+ */
63
+ deniedFromRows(rows: MembershipRow[]): string[];
56
64
  }
@@ -80,6 +80,8 @@ let MembershipService = class MembershipService {
80
80
  routeGroup: rowGroup,
81
81
  organizationId: rowOrg,
82
82
  permissions: ur.permissions,
83
+ grantedPermissions: ur.grantedPermissions ?? ur.granted_permissions,
84
+ deniedPermissions: ur.deniedPermissions ?? ur.denied_permissions,
83
85
  role: ur.role,
84
86
  });
85
87
  }
@@ -93,13 +95,26 @@ let MembershipService = class MembershipService {
93
95
  return this.matchingRows(user, routeGroup, organization, isTenant).length > 0;
94
96
  }
95
97
  /**
96
- * Permissions granted to the user from the matched membership rows only
98
+ * ALLOW permissions resolved from the matched membership rows only
97
99
  * (design §6: "permissions then resolve from that matching membership row").
100
+ * Layered: each row contributes legacy ∪ granted ∪ org role layer.
98
101
  */
99
102
  permissionsFromRows(rows) {
100
103
  const out = [];
101
104
  for (const r of rows) {
102
- for (const p of (0, permission_matcher_1.coercePermissions)(r.permissions))
105
+ for (const p of (0, permission_matcher_1.rowAllowPermissions)(r))
106
+ out.push(p);
107
+ }
108
+ return out;
109
+ }
110
+ /**
111
+ * DENY permissions resolved from the matched membership rows. Deny always
112
+ * wins over the allow set ({@link permissionsFromRows}).
113
+ */
114
+ deniedFromRows(rows) {
115
+ const out = [];
116
+ for (const r of rows) {
117
+ for (const p of (0, permission_matcher_1.rowDeniedPermissions)(r))
103
118
  out.push(p);
104
119
  }
105
120
  return out;
@@ -1 +1 @@
1
- {"version":3,"file":"membership.service.js","sourceRoot":"","sources":["../../src/services/membership.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"membership.service.js","sourceRoot":"","sources":["../../src/services/membership.service.ts"],"names":[],"mappings":"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"}