@vertesia/common 1.1.1-dev.20260505.163000Z → 1.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.
Files changed (46) hide show
  1. package/lib/cjs/access-control.js +34 -1
  2. package/lib/cjs/access-control.js.map +1 -1
  3. package/lib/cjs/apikey.js.map +1 -1
  4. package/lib/cjs/group.js +1 -1
  5. package/lib/cjs/group.js.map +1 -1
  6. package/lib/cjs/project.js.map +1 -1
  7. package/lib/cjs/store/store.js.map +1 -1
  8. package/lib/cjs/user.js.map +1 -1
  9. package/lib/esm/access-control.js +32 -0
  10. package/lib/esm/access-control.js.map +1 -1
  11. package/lib/esm/apikey.js.map +1 -1
  12. package/lib/esm/group.js +1 -1
  13. package/lib/esm/group.js.map +1 -1
  14. package/lib/esm/project.js.map +1 -1
  15. package/lib/esm/store/store.js.map +1 -1
  16. package/lib/esm/user.js.map +1 -1
  17. package/lib/tsconfig.tsbuildinfo +1 -1
  18. package/lib/types/access-control.d.ts +57 -2
  19. package/lib/types/access-control.d.ts.map +1 -1
  20. package/lib/types/apikey.d.ts +14 -0
  21. package/lib/types/apikey.d.ts.map +1 -1
  22. package/lib/types/environment.d.ts +1 -0
  23. package/lib/types/environment.d.ts.map +1 -1
  24. package/lib/types/group.d.ts +13 -1
  25. package/lib/types/group.d.ts.map +1 -1
  26. package/lib/types/oauth-server.d.ts +17 -0
  27. package/lib/types/oauth-server.d.ts.map +1 -1
  28. package/lib/types/project.d.ts +25 -27
  29. package/lib/types/project.d.ts.map +1 -1
  30. package/lib/types/store/collections.d.ts +8 -0
  31. package/lib/types/store/collections.d.ts.map +1 -1
  32. package/lib/types/store/store.d.ts +4 -0
  33. package/lib/types/store/store.d.ts.map +1 -1
  34. package/lib/types/user.d.ts +9 -0
  35. package/lib/types/user.d.ts.map +1 -1
  36. package/lib/vertesia-common.js +1 -1
  37. package/lib/vertesia-common.js.map +1 -1
  38. package/package.json +2 -2
  39. package/src/access-control.ts +73 -0
  40. package/src/apikey.ts +16 -0
  41. package/src/group.ts +13 -1
  42. package/src/oauth-server.ts +18 -0
  43. package/src/project.ts +26 -27
  44. package/src/store/collections.ts +8 -0
  45. package/src/store/store.ts +4 -0
  46. package/src/user.ts +9 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/common",
3
- "version": "1.1.1-dev.20260505.163000Z",
3
+ "version": "1.3.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "types": "./lib/types/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "ajv": "^8.17.1",
29
- "@llumiverse/common": "1.1.1-dev.20260505.151157Z"
29
+ "@llumiverse/common": "1.3.0"
30
30
  },
31
31
  "repository": {
32
32
  "type": "git",
@@ -58,22 +58,64 @@ export enum AccessControlResourceType {
58
58
  account = "account",
59
59
  interaction = "interaction",
60
60
  app = "application",
61
+ /** Dynamic resource matching by content properties at query time. */
62
+ content_set = "content_set",
61
63
  }
62
64
 
63
65
  export enum AccessControlPrincipalType {
64
66
  user = "user",
65
67
  group = "group",
66
68
  apikey = "apikey",
69
+ /** Dynamic principal matching by user/group properties at token time. */
70
+ principal_set = "principal_set",
67
71
  }
68
72
 
69
73
 
70
74
 
75
+ /**
76
+ * MongoDB query syntax subset for matching properties.
77
+ * Keys are property names, values are either direct match values or operator objects.
78
+ * Supported operators: `$eq`, `$ne`, `$gt`, `$gte`, `$lt`, `$lte`, `$in`, `$nin`, `$exists`.
79
+ *
80
+ * In `resource_props`, values can reference principal properties using the `$principal.` prefix.
81
+ * These are resolved at token time by substituting the user's merged property value.
82
+ * If the referenced property is missing, a type-appropriate default is used (0, "", false).
83
+ *
84
+ * @example
85
+ * { department: "engineering" } // exact match (literal)
86
+ * { level: { $gte: 5 } } // comparison (literal)
87
+ * { region: { $in: ["us-east", "eu-west"] } } // set membership (literal)
88
+ * { security_level: { $lte: "$principal.access_level" } } // cross-reference (resolved at token time)
89
+ */
90
+ /** A single condition value: literal, or operator object (e.g. { $lte: 3 }) */
91
+ export type PropertyConditionValue = string | number | boolean | Record<string, any>;
92
+
93
+ export type PropertyConditions = Record<string, PropertyConditionValue>;
94
+
95
+ /**
96
+ * Conditions attached to an ACE for dynamic matching.
97
+ * - `principal_props`: matched against user/group properties at token time (PrincipalSet).
98
+ * - `resource_props`: matched against content properties at query time (ContentSet).
99
+ */
100
+ export interface AceConditions {
101
+ /** Property conditions matched against user/group properties at token time (PrincipalSet). */
102
+ principal_props?: PropertyConditions;
103
+ /** Property conditions matched against content properties at query time (ContentSet). */
104
+ resource_props?: PropertyConditions;
105
+ }
106
+
71
107
  export interface AccessControlEntry {
72
108
  role: ProjectRoles;
73
109
  resource_type: AccessControlResourceType;
74
110
  resource: string; //objectId
75
111
  principal_type: AccessControlPrincipalType;
76
112
  principal: string; //objectId
113
+ /** Account scope — required for principal_set/content_set ACEs. */
114
+ account?: string;
115
+ /** Project scope — narrows a principal_set/content_set ACE to a single project. */
116
+ project?: string;
117
+ /** Dynamic matching conditions for principal_set/content_set ACEs. */
118
+ conditions?: AceConditions;
77
119
  tags?: string[];
78
120
  expires_at?: string;
79
121
  created_at?: string;
@@ -93,6 +135,37 @@ export interface RoleDefinition {
93
135
  permissions: Permission[];
94
136
  }
95
137
 
138
+ // ============================================================================
139
+ // BLP Security Levels
140
+ // ============================================================================
141
+
142
+ /**
143
+ * Default sensitivity/clearance levels for the Bell-LaPadula security model.
144
+ * The numeric value is the index in the array (0 = lowest, 4 = highest).
145
+ * Projects can override these labels via project settings.
146
+ */
147
+ export enum SecurityLevel {
148
+ public = 0,
149
+ internal = 1,
150
+ confidential = 2,
151
+ restricted = 3,
152
+ secret = 4,
153
+ }
154
+
155
+ /** Human-readable labels for each security level, indexed by numeric value. */
156
+ export const SecurityLevelLabels: readonly string[] = [
157
+ 'Public',
158
+ 'Internal',
159
+ 'Confidential',
160
+ 'Restricted',
161
+ 'Secret',
162
+ ];
163
+
164
+ /** Get the label for a security level value. Returns "Unknown" for out-of-range values. */
165
+ export function getSecurityLevelLabel(level: number): string {
166
+ return SecurityLevelLabels[level] ?? 'Unknown';
167
+ }
168
+
96
169
  export interface AcesQueryOptions {
97
170
 
98
171
  level?: 'resource' | 'project' | 'projects' | 'account'
package/src/apikey.ts CHANGED
@@ -1,7 +1,19 @@
1
+ import { PropertyConditions } from "./access-control.js";
1
2
  import { UserGroupRef } from "./group.js";
2
3
  import { ProjectRef, ProjectRoles } from "./project.js";
3
4
  import { AccountRef } from "./user.js";
4
5
 
6
+ /**
7
+ * Content security conditions in the JWT, keyed by permission type.
8
+ * Each key maps to an array of condition sets — at query time, any matching set grants access ($or).
9
+ * Presence of this object in the JWT switches content access from allow-all to restrict mode.
10
+ */
11
+ export interface ContentSecurity {
12
+ read?: PropertyConditions[];
13
+ write?: PropertyConditions[];
14
+ delete?: PropertyConditions[];
15
+ }
16
+
5
17
  export enum ApiKeyTypes {
6
18
  secret = "sk",
7
19
  }
@@ -80,6 +92,10 @@ export interface AuthTokenPayload {
80
92
  /** groups */
81
93
  groups?: UserGroupRef[]; //group ids
82
94
 
95
+ /** Content security conditions keyed by permission (read/write/delete).
96
+ * Presence triggers restrict mode: project:* is dropped from security filters. */
97
+ content_security?: ContentSecurity;
98
+
83
99
  /**
84
100
  * API endpoints information to be used with this token.
85
101
  * Either a n API domain like 'api.vertesia.io' | 'api-preview.vertesia.io' | 'api-staging.vertesia.io' | 'local'
package/src/group.ts CHANGED
@@ -11,6 +11,12 @@ export interface UserGroup {
11
11
  updated_at: Date;
12
12
  created_by?: string;
13
13
  updated_by?: string;
14
+ /** Custom properties for dynamic permission matching */
15
+ properties?: Record<string, any>;
16
+ /** BLP clearance level — merged with user clearance using max() */
17
+ clearance?: number;
18
+ /** Compartments — merged with user compartments using array union */
19
+ compartments?: string[];
14
20
  }
15
21
 
16
22
  export interface PopulatesUserGroup extends UserGroup {
@@ -27,14 +33,20 @@ export interface UpdateUserGroupPayload {
27
33
  name: string;
28
34
  description?: string;
29
35
  tags?: string[];
36
+ properties?: Record<string, any>;
37
+ clearance?: number;
38
+ compartments?: string[];
30
39
  }
31
40
 
32
41
  export interface UserGroupRef {
33
42
  id: string;
34
43
  name: string;
35
44
  tags?: string[];
45
+ properties?: Record<string, any>;
46
+ clearance?: number;
47
+ compartments?: string[];
36
48
  }
37
49
 
38
- export const UserGroupRefPopulate = 'id name tags description';
50
+ export const UserGroupRefPopulate = 'id name tags description properties clearance compartments';
39
51
 
40
52
  export const MEMBERS_GROUP_NAME = 'members';
@@ -256,3 +256,21 @@ export interface OAuthAccessTokenPayload extends Omit<AuthTokenPayload, 'type' |
256
256
  allowed_collections?: string[];
257
257
  resource?: string;
258
258
  }
259
+
260
+ export interface OAuthIdTokenPayload {
261
+ sub: string;
262
+ user_id: string;
263
+ name: string;
264
+ email?: string;
265
+ picture?: string;
266
+ type: 'oauth_id';
267
+ client_id: string;
268
+ account: AuthTokenPayload['account'];
269
+ accounts: AuthTokenPayload['accounts'];
270
+ project?: ProjectRef;
271
+ /** User groups */
272
+ groups?: AuthTokenPayload['groups'];
273
+ iss: string;
274
+ aud: string;
275
+ exp: number;
276
+ }
package/src/project.ts CHANGED
@@ -211,6 +211,13 @@ export interface ProjectConfiguration {
211
211
  */
212
212
  main_language?: string;
213
213
 
214
+ /**
215
+ * Object ID of a content object containing a custom LaTeX template (.latex file)
216
+ * to use as the branded PDF template. When set, "Export as Branded PDF" uses this
217
+ * template instead of the built-in Vertesia default template.
218
+ */
219
+ pdf_template_object_id?: string;
220
+
214
221
  }
215
222
 
216
223
  // export interface ProjectConfigurationEmbeddings {
@@ -321,40 +328,32 @@ export interface IndexingStatusResponse {
321
328
  reindex_in_progress: boolean;
322
329
  /** Reindex progress (if reindex is in progress) */
323
330
  reindex_progress?: {
324
- /** Total documents to reindex */
325
- total: number;
326
- /** Documents processed so far */
327
- processed: number;
328
- /** Successfully indexed documents */
329
- successful: number;
330
- /** Failed documents */
331
- failed: number;
332
- /** Current status (e.g., "indexing", "complete") */
331
+ /** Total shards to process */
332
+ total_shards: number;
333
+ /** Shards completed so far */
334
+ completed_shards: number;
335
+ /** Shards that failed */
336
+ failed_shards: number;
337
+ /** Current status (e.g., "computing_shards", "indexing", "completed") */
333
338
  status: string;
334
- /** Current batch number */
335
- current_batch: number;
336
- /** Total number of batches */
337
- total_batches: number;
338
- /** Percentage complete (0-100) */
339
- percent_complete: number;
340
- /** Batches processed per second */
341
- batches_per_second: number;
339
+ /** Documents scanned from source */
340
+ scanned: number;
341
+ /** Documents written to target index */
342
+ written: number;
343
+ /** Documents that failed to index */
344
+ errors: number;
342
345
  /** Documents processed per second */
343
346
  docs_per_second: number;
344
347
  /** Elapsed time in seconds */
345
348
  elapsed_seconds: number;
346
349
  /** Estimated seconds remaining (null if unknown) */
347
350
  estimated_seconds_remaining: number | null;
348
- /** Total bytes sent to ES */
349
- total_bytes?: number;
350
- /** Total ES bulk flushes */
351
- bulk_flushes?: number;
352
- /** Average bytes per ES bulk flush */
353
- avg_flush_bytes?: number;
354
- /** Configured batch size */
355
- batch_size?: number;
356
- /** Configured parallel batch count */
357
- parallel_batch_count?: number;
351
+ /** Percentage complete (0-100) */
352
+ percent_complete: number;
353
+ /** Source alias */
354
+ alias: string;
355
+ /** Target index name */
356
+ target_index: string;
358
357
  };
359
358
  }
360
359
 
@@ -20,6 +20,10 @@ export interface CreateCollectionPayload {
20
20
  allowed_types?: string[];
21
21
  updated_by?: string,
22
22
  shared_properties?: string[];
23
+ /** BLP sensitivity level for member documents */
24
+ sensitivity?: number;
25
+ /** Compartments for member documents */
26
+ compartments?: string[];
23
27
  }
24
28
 
25
29
  export interface CollectionItem extends BaseObject {
@@ -58,6 +62,10 @@ export interface Collection extends CollectionItem {
58
62
  properties: Record<string, any>;
59
63
  query?: Record<string, any>;
60
64
  security?: Record<string, string[]>; // ACL for collection access
65
+ /** BLP sensitivity level — propagated to member documents (max across collections) */
66
+ sensitivity?: number;
67
+ /** Compartments — propagated to member documents (union across collections) */
68
+ compartments?: string[];
61
69
  /**
62
70
  * List of property names from the collection's properties that should be shared with (injected into) member objects.
63
71
  * These properties will be propagated to all members of this collection and merged as arrays.
@@ -151,6 +151,10 @@ export interface ContentObject<T = any> extends ContentObjectItem<T> {
151
151
  parts_etag?: string; // the etag of the text used for the parts list
152
152
  transcript?: Transcript;
153
153
  security?: Record<string, string[]>; // Security field for granular permissions
154
+ /** BLP sensitivity level — set directly or inherited from collections (max across collections). */
155
+ sensitivity?: number;
156
+ /** Compartments — set directly or inherited from collections (union across collections). */
157
+ compartments?: string[];
154
158
 
155
159
  /**
156
160
  * Inherited properties metadata - tracks which properties were inherited from parent collections.
package/src/user.ts CHANGED
@@ -19,6 +19,12 @@ export interface User {
19
19
  last_selected_account?: string;
20
20
  source?: 'firebase' | 'scim';
21
21
  updated_by?: string;
22
+ /** Custom properties for dynamic permission matching */
23
+ properties?: Record<string, any>;
24
+ /** BLP clearance level — determines max document sensitivity the user can access */
25
+ clearance?: number;
26
+ /** Compartments the user belongs to — restricts access to documents in matching compartments */
27
+ compartments?: string[];
22
28
  }
23
29
 
24
30
 
@@ -29,6 +35,9 @@ export interface UpdateUserPayload {
29
35
  language?: string;
30
36
  phone?: string;
31
37
  last_selected_account?: string;
38
+ properties?: Record<string, any>;
39
+ clearance?: number;
40
+ compartments?: string[];
32
41
  }
33
42
 
34
43