@appxdigital/appx-core 0.1.121-beta.9 → 0.1.121

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Static validation of a `PermissionsConfig` against the Prisma schema.
3
+ *
4
+ * Runs at boot (in the PrismaService constructor). It encodes the Option A
5
+ * authorization model: a create condition judges a model's own scalar fields
6
+ * only, and every foreign-key reference a create establishes is authorized by
7
+ * the target model's `connect` rule. Misconfigurations that would break at
8
+ * runtime are surfaced here — errors reject boot, warnings are advisory.
9
+ *
10
+ * Pure and schema-only (no database), so it is independently unit-testable.
11
+ */
12
+ import type { PermissionsConfigType } from '../common/config/permissionsConfigTypes';
13
+ export type RelationKind = 'belongsTo' | 'hasMany';
14
+ export interface RelationMeta {
15
+ /** The relation navigation field name on the owning model. */
16
+ field: string;
17
+ /** The target model name (original casing, as in the schema). */
18
+ model: string;
19
+ /** The owning model's scalar FK column (belongsTo only). */
20
+ referencingColumn?: string;
21
+ isRequired: boolean;
22
+ kind: RelationKind;
23
+ /** False when the scalar FK is @NoWrite / @Role(none) (never client-writable). Defaults to writable. */
24
+ fkWritable?: boolean;
25
+ }
26
+ /** Relations per model, keyed by the lower-cased model name. */
27
+ export type SchemaRelations = Record<string, RelationMeta[]>;
28
+ export type IssueLevel = 'error' | 'warning';
29
+ export type IssueCode = 'relation-in-create-condition' | 'missing-connect-required' | 'missing-connect' | 'connect-on-unwritable' | 'unknown-relation';
30
+ export interface ValidationIssue {
31
+ level: IssueLevel;
32
+ code: IssueCode;
33
+ model: string;
34
+ role: string;
35
+ message: string;
36
+ }
37
+ /**
38
+ * Validates the permissions config against the schema relations.
39
+ *
40
+ * Checks, per model + role that can create the model:
41
+ * - **error** `relation-in-create-condition` — a create condition references a
42
+ * relation. Create conditions are own-scalar-only; relationship checks belong
43
+ * on the target's `connect` rule.
44
+ * - **error** `missing-connect-required` — a *required* belongsTo FK's target
45
+ * has no `connect` rule for the role. Every create sets it, so it will always
46
+ * be denied at runtime.
47
+ * - **warning** `missing-connect-optional` — an *optional* belongsTo FK's target
48
+ * has no `connect` rule for the role. Only denied when the payload sets it.
49
+ */
50
+ export declare function validatePermissionsConfig(config: PermissionsConfigType, relations: SchemaRelations): ValidationIssue[];
51
+ //# sourceMappingURL=permissions-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-validator.d.ts","sourceRoot":"","sources":["../../src/prisma/permissions-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAErF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAEnD,MAAM,WAAW,YAAY;IACzB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,wGAAwG;IACxG,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;AAE7D,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7C,MAAM,MAAM,SAAS,GACf,8BAA8B,GAC9B,0BAA0B,GAC1B,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,CAAC;AAEzB,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAmBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACrC,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,eAAe,GAC3B,eAAe,EAAE,CAmHnB"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatePermissionsConfig = void 0;
4
+ /** Collects condition keys that name a relation (skips AND/OR/NOT, which recurse). */
5
+ function findRelationKeys(cond, relationFields, found = new Set()) {
6
+ if (!cond || typeof cond !== 'object')
7
+ return found;
8
+ const objs = Array.isArray(cond) ? cond : [cond];
9
+ for (const obj of objs) {
10
+ if (!obj || typeof obj !== 'object')
11
+ continue;
12
+ for (const key of Object.keys(obj)) {
13
+ if (key === 'AND' || key === 'OR' || key === 'NOT') {
14
+ findRelationKeys(obj[key], relationFields, found);
15
+ continue;
16
+ }
17
+ if (relationFields.has(key))
18
+ found.add(key);
19
+ }
20
+ }
21
+ return found;
22
+ }
23
+ /**
24
+ * Validates the permissions config against the schema relations.
25
+ *
26
+ * Checks, per model + role that can create the model:
27
+ * - **error** `relation-in-create-condition` — a create condition references a
28
+ * relation. Create conditions are own-scalar-only; relationship checks belong
29
+ * on the target's `connect` rule.
30
+ * - **error** `missing-connect-required` — a *required* belongsTo FK's target
31
+ * has no `connect` rule for the role. Every create sets it, so it will always
32
+ * be denied at runtime.
33
+ * - **warning** `missing-connect-optional` — an *optional* belongsTo FK's target
34
+ * has no `connect` rule for the role. Only denied when the payload sets it.
35
+ */
36
+ function validatePermissionsConfig(config, relations) {
37
+ const issues = [];
38
+ // Iterate the typed config structurally — model/role keys are dynamic, and
39
+ // condition/rule shapes are inspected at runtime.
40
+ const cfg = (config || {});
41
+ const byModel = {};
42
+ for (const m of Object.keys(cfg))
43
+ byModel[m.toLowerCase()] = cfg[m];
44
+ const hasConnectRule = (targetModel, role) => {
45
+ const rules = byModel[targetModel.toLowerCase()]?.[role];
46
+ return !!rules && rules.connect !== undefined && rules.connect !== null;
47
+ };
48
+ // A relation-scoped connect on the source (creating) model authorizes that
49
+ // relation on its own — the target model then needs no connect rule.
50
+ const hasRelationConnect = (sourceRules, field) => !!sourceRules?.relations?.[field]?.connect;
51
+ const canCreate = (rules) => !!rules && (rules.create !== undefined || rules.createMany !== undefined);
52
+ const canUpdate = (rules) => !!rules && (rules.update !== undefined || rules.updateMany !== undefined);
53
+ for (const modelKey of Object.keys(cfg)) {
54
+ const roles = cfg[modelKey] || {};
55
+ const rels = relations[modelKey.toLowerCase()] || [];
56
+ const belongsTo = rels.filter((r) => r.kind === 'belongsTo' && r.referencingColumn);
57
+ const relationFieldNames = new Set(rels.map((r) => r.field));
58
+ for (const role of Object.keys(roles)) {
59
+ const rules = roles[role];
60
+ const creatable = canCreate(rules);
61
+ const updatable = canUpdate(rules);
62
+ if (!creatable && !updatable)
63
+ continue;
64
+ const createRule = rules.create ?? rules.createMany;
65
+ const conditions = createRule && typeof createRule === 'object' ? createRule.conditions : undefined;
66
+ if (conditions) {
67
+ for (const relField of findRelationKeys(conditions, relationFieldNames)) {
68
+ issues.push({
69
+ level: 'error',
70
+ code: 'relation-in-create-condition',
71
+ model: modelKey,
72
+ role,
73
+ message: `create condition on ${modelKey}.${role} references relation '${relField}'. Create conditions judge own scalar fields only — authorize relationships with the target model's 'connect' rule.`,
74
+ });
75
+ }
76
+ }
77
+ // Every foreign key a write can SET must have a connect rule (target
78
+ // or relation-scoped) — otherwise setting it is denied at runtime.
79
+ // A @NoWrite / @Role(none) column is never settable.
80
+ for (const r of belongsTo) {
81
+ const col = r.referencingColumn;
82
+ const writable = r.fkWritable !== false; // not @NoWrite / @Role(none)
83
+ const settableOnCreate = writable && creatable;
84
+ const settableOnUpdate = writable && updatable;
85
+ const relRule = hasRelationConnect(rules, r.field);
86
+ if (!settableOnCreate && !settableOnUpdate) {
87
+ // A relation-scoped connect rule for a field that can't be
88
+ // written is contradictory — flag it rather than silently ignore.
89
+ if (relRule) {
90
+ issues.push({
91
+ level: 'error',
92
+ code: 'connect-on-unwritable',
93
+ model: modelKey,
94
+ role,
95
+ message: `${modelKey}.${role}.relations.${r.field}.connect is set, but its foreign key '${col}' is not writable (@NoWrite / @Role(none)). Make the field writable or remove the relation rule.`,
96
+ });
97
+ }
98
+ continue;
99
+ }
100
+ if (relRule || hasConnectRule(r.model, role))
101
+ continue;
102
+ const fix = `Declare '${r.model}.${role}.connect' (or 'ALL'), or scope it to this relation with '${modelKey}.${role}.relations.${r.field}.connect'.`;
103
+ if (settableOnCreate && r.isRequired) {
104
+ issues.push({
105
+ level: 'error',
106
+ code: 'missing-connect-required',
107
+ model: modelKey,
108
+ role,
109
+ message: `${modelKey}.${role} can create, but its required foreign key '${col}' → ${r.model} has no 'connect' rule for ${role}. Every create sets it, so the create is always denied. ${fix}`,
110
+ });
111
+ }
112
+ else {
113
+ issues.push({
114
+ level: 'error',
115
+ code: 'missing-connect',
116
+ model: modelKey,
117
+ role,
118
+ message: `${modelKey}.${role} can set foreign key '${col}' → ${r.model} (on ${settableOnCreate ? 'create' : ''}${settableOnCreate && settableOnUpdate ? '/' : ''}${settableOnUpdate ? 'update' : ''}), but ${r.model} has no 'connect' rule for ${role}, so any write that sets it is denied. ${fix}`,
119
+ });
120
+ }
121
+ }
122
+ // A `relations` key that doesn't name a real relation of this model is
123
+ // almost certainly a typo — it silently does nothing.
124
+ const relationsMap = rules.relations;
125
+ if (relationsMap && typeof relationsMap === 'object') {
126
+ for (const relField of Object.keys(relationsMap)) {
127
+ if (!relationFieldNames.has(relField)) {
128
+ issues.push({
129
+ level: 'warning',
130
+ code: 'unknown-relation',
131
+ model: modelKey,
132
+ role,
133
+ message: `${modelKey}.${role}.relations.${relField} does not name a relation of ${modelKey} — it has no effect. Check the field name.`,
134
+ });
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ return issues;
141
+ }
142
+ exports.validatePermissionsConfig = validatePermissionsConfig;
@@ -52,6 +52,13 @@ export declare class PrismaService {
52
52
  */
53
53
  private rawClient;
54
54
  constructor(prismaClient: PrismaClient, permissionsConfig: PermissionsConfigType);
55
+ /**
56
+ * Validates the permissions config against the schema at boot. Warnings are
57
+ * logged; errors (a create condition that crosses a relation, or a required
58
+ * FK whose target has no `connect` rule) reject boot — the misconfiguration
59
+ * would otherwise surface as a runtime 403.
60
+ */
61
+ private validatePermissions;
55
62
  debugQueries(enable: boolean): void;
56
63
  withExposedModels(models: string[], callback: () => Promise<void>): Promise<void>;
57
64
  private debug;
@@ -114,6 +121,43 @@ export declare class PrismaService {
114
121
  * cannot evaluate, rather than silently allowing the insert.
115
122
  */
116
123
  private enforceCreateConditions;
124
+ /**
125
+ * Authorizes every relation a write establishes. Relationship authorization
126
+ * lives entirely in the `connect` action — create conditions judge a model's
127
+ * own scalar fields only.
128
+ *
129
+ * Runs on create AND update: a `create` can nest relation writes or set raw
130
+ * FKs; an `updateMany` (scalar-only) can re-point a raw FK. Both go through
131
+ * the same `connect` authorization.
132
+ *
133
+ * - A raw scalar foreign key (`courseId: 7`) → the target's `connect` rule.
134
+ * - `relation: { connect }` → the target's `connect` rule. `connect` is a
135
+ * DEDICATED action: being allowed to READ a record does not authorize
136
+ * associating it.
137
+ * - `relation: { create }` → the target's `create` rule (recurses, so deeper
138
+ * nesting is authorized too). Every other nested operator is rejected.
139
+ *
140
+ * The one exception is `trustedFk`: the scalar FK that points back to the row
141
+ * we're nested under. Prisma fills it at write time and the parent already
142
+ * authorized itself, so it is not re-checked.
143
+ */
144
+ private enforceNestedWrites;
145
+ /** Authorizes each operator inside one relation's nested-write object. */
146
+ private enforceNestedRelationOps;
147
+ /** If `column` is the scalar FK backing a belongsTo relation, returns that relation's field + target. */
148
+ private foreignKeyColumn;
149
+ /** The child's scalar FK column pointing back to the parent it's nested under (trusted). */
150
+ private backReferenceFk;
151
+ /**
152
+ * Authorizes attaching `relatedModel` (identified by `where`) through the
153
+ * `field` relation on `sourceModel`. Two rules can apply, evaluated against
154
+ * the candidate target row:
155
+ * - a relation-scoped rule on the source (`sourceModel[role].relations[field].connect`)
156
+ * - the target model's own rule (`relatedModel[role].connect`)
157
+ * When both exist they are ANDed (the relation rule can only strengthen).
158
+ * When only one exists it stands alone; when neither exists, default-deny.
159
+ */
160
+ private assertConnectAllowed;
117
161
  /**
118
162
  * True only in an explicit local-development environment. Deliberately NOT
119
163
  * `!== 'production'` — staging and other envs should behave like production
@@ -128,12 +172,25 @@ export declare class PrismaService {
128
172
  * (gated by the caller).
129
173
  */
130
174
  private warnIfCreatedRowNotFindable;
131
- /** Recursively evaluates a (placeholder-resolved) condition object against a to-be-created row. */
175
+ /**
176
+ * A view of a create `row` where a belongsTo relation given via `connect`
177
+ * (`owner: { connect: { id } }`) is also surfaced as its scalar FK (`ownerId`),
178
+ * so scalar-FK create conditions match either payload form. Metadata-driven
179
+ * (`referencingColumn`/`foreignKey`); resolvable only when the connect targets
180
+ * the referenced column. Explicit scalar wins; row is not mutated.
181
+ */
182
+ private resolveConnectForeignKeys;
183
+ /**
184
+ * Evaluates a (placeholder-resolved) create condition against a to-be-created
185
+ * row. Create conditions judge the model's OWN scalar fields only — a clause
186
+ * that reaches into a relation is not a create concern (relationships are
187
+ * authorized by the target's `connect` rule) and is skipped here; the config
188
+ * validator rejects such clauses at boot. `trustedFk` (the back-reference to a
189
+ * same-request nesting parent) is likewise skipped — its value doesn't exist yet.
190
+ */
132
191
  private matchesCreateConditions;
133
192
  /** Evaluates a scalar-field condition (value or Prisma operator object) against the row's value. */
134
193
  private matchesCreateScalar;
135
- /** Verifies the parent referenced by a belongsTo condition exists and satisfies the nested condition. */
136
- private matchesCreateRelation;
137
194
  /**
138
195
  * Builds dynamic conditions based on the type of clause (OR, AND, or field conditions).
139
196
  * Each condition is processed, and placeholders (like `$USER_ID`) are replaced with actual values.
@@ -178,6 +235,7 @@ export declare class PrismaService {
178
235
  relation: string;
179
236
  foreignKey?: string;
180
237
  referencingColumn?: string;
238
+ relationName?: string;
181
239
  isRequired: boolean;
182
240
  };
183
241
  selectPermission(permissions: any, action: string, modelName: string, userRole: string): any;
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.service.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prisma.service.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.service.ts"],"names":[],"mappings":"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"}