roboto-js 1.7.5 → 1.8.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.
package/.last-build CHANGED
@@ -1 +1 @@
1
- 2025-10-02T14:56:57.111Z
1
+ 2025-10-08T10:39:00.776Z
@@ -0,0 +1,483 @@
1
+ # Object Sharing and Access Control Guide for roboto-js
2
+
3
+ This guide explains how to use the new access control and publishing methods in roboto-js to control access to your rbtObjects using the mod-iac (Identity and Access Control) system.
4
+
5
+ ## Table of Contents
6
+ - [Overview](#overview)
7
+ - [Public Publishing](#public-publishing)
8
+ - [Granting Access to Users and Groups](#granting-access-to-users-and-groups)
9
+ - [Revoking Access](#revoking-access)
10
+ - [Advanced Usage](#advanced-usage)
11
+ - [API Reference](#api-reference)
12
+
13
+ ## Overview
14
+
15
+ The mod-iac system manages object permissions through an `iac` property on each rbtObject. This property contains:
16
+
17
+ - **`creator`**: The user ID who created the object
18
+ - **`readGrants`**: Controls who can read the object
19
+ - **`writeGrants`**: Controls who can modify the object
20
+
21
+ Each grant can include:
22
+ - `users`: Array of user IDs
23
+ - `userGroups`: Array of user group IDs
24
+ - `organizations`: Array of organization IDs
25
+ - `userSegments`: Array of user segment IDs
26
+
27
+ ## Public Publishing
28
+
29
+ ### Making an Object Public
30
+
31
+ The simplest way to share an object with everyone is to publish it:
32
+
33
+ ```javascript
34
+ // Load your object
35
+ const myAgent = await roboto.api.load('<@doc_agent.bot>', 'agentId');
36
+
37
+ // Publish it (make it publicly accessible)
38
+ await myAgent.publishObject();
39
+
40
+ console.log('Agent is now public!');
41
+ ```
42
+
43
+ ### Unpublishing an Object
44
+
45
+ To remove public access:
46
+
47
+ ```javascript
48
+ // Unpublish the object (explicit method)
49
+ await myAgent.unpublishObject();
50
+
51
+ console.log('Agent is now private');
52
+
53
+ // Alternative: using publishObject with flag
54
+ await myAgent.publishObject({ publish: false });
55
+ ```
56
+
57
+ ### Checking Publication Status
58
+
59
+ ```javascript
60
+ if (myAgent.isPublished()) {
61
+ console.log('This object is public');
62
+ } else {
63
+ console.log('This object is private');
64
+ }
65
+ ```
66
+
67
+ ## Granting Access to Users and Groups
68
+
69
+ ### Grant Access to Specific Users
70
+
71
+ ```javascript
72
+ // Grant read access to specific user IDs
73
+ await myAgent.grantAccess({
74
+ userIds: ['user_123', 'user_456']
75
+ });
76
+
77
+ console.log('Granted access to 2 users');
78
+ ```
79
+
80
+ ### Grant Access to User Groups
81
+
82
+ ```javascript
83
+ // Grant read access to user groups
84
+ await myAgent.grantAccess({
85
+ groupIds: ['grpRngAccount', 'grpAdmins']
86
+ });
87
+
88
+ console.log('Granted access to 2 groups');
89
+ ```
90
+
91
+ ### Grant Access to Both Users and Groups
92
+
93
+ ```javascript
94
+ // Combine users and groups
95
+ await myAgent.grantAccess({
96
+ userIds: ['user_123'],
97
+ groupIds: ['grpRngAccount', 'grpAdmins']
98
+ });
99
+ ```
100
+
101
+ ### Grant Write Access
102
+
103
+ By default, `grantAccess` grants read access. To grant write access:
104
+
105
+ ```javascript
106
+ // Grant write access to specific users
107
+ await myAgent.grantAccess({
108
+ userIds: ['user_123', 'user_456'],
109
+ write: true
110
+ });
111
+
112
+ console.log('Users can now modify this object');
113
+ ```
114
+
115
+ ## Revoking Access
116
+
117
+ ### Revoke Access from Specific Users
118
+
119
+ ```javascript
120
+ // Revoke read access from specific users
121
+ await myAgent.revokeAccess({
122
+ userIds: ['user_123', 'user_456']
123
+ });
124
+
125
+ console.log('Revoked access from 2 users');
126
+ ```
127
+
128
+ ### Revoke Access from User Groups
129
+
130
+ ```javascript
131
+ // Revoke read access from user groups
132
+ await myAgent.revokeAccess({
133
+ groupIds: ['grpRngAccount']
134
+ });
135
+
136
+ console.log('Revoked access from group');
137
+ ```
138
+
139
+ ### Revoke Write Access
140
+
141
+ ```javascript
142
+ // Revoke write access from specific groups
143
+ await myAgent.revokeAccess({
144
+ groupIds: ['grpEditors'],
145
+ write: true
146
+ });
147
+
148
+ console.log('Revoked write access from editors');
149
+ ```
150
+
151
+ ## Advanced Usage
152
+
153
+ ### Merging vs. Replacing Permissions
154
+
155
+ By default, `grantAccess` merges with existing permissions. Use `replace: true` to replace them entirely:
156
+
157
+ ```javascript
158
+ // Add to existing permissions (default)
159
+ await myAgent.grantAccess({
160
+ userIds: ['user_123']
161
+ });
162
+ // Now includes: existing users + user_123
163
+
164
+ // Replace all permissions
165
+ await myAgent.grantAccess({
166
+ userIds: ['user_789'],
167
+ replace: true
168
+ });
169
+ // Now includes: only user_789
170
+ ```
171
+
172
+ ### Update Without Auto-Saving
173
+
174
+ All methods auto-save by default. You can disable this to make multiple changes:
175
+
176
+ ```javascript
177
+ // Update permissions without saving
178
+ await myAgent.grantAccess({
179
+ userIds: ['user_123'],
180
+ save: false
181
+ });
182
+
183
+ // Make other changes
184
+ myAgent.set('configs.title', 'Updated Title');
185
+
186
+ // Publish without saving
187
+ await myAgent.publishObject({ save: false });
188
+
189
+ // Save once with all changes
190
+ await myAgent.save();
191
+ ```
192
+
193
+ ### Getting Current Sharing Permissions
194
+
195
+ ```javascript
196
+ // Get all current permissions
197
+ const permissions = myAgent.getSharing();
198
+
199
+ console.log('Read access users:', permissions.readGrants.users);
200
+ console.log('Read access groups:', permissions.readGrants.userGroups);
201
+ console.log('Write access users:', permissions.writeGrants.users);
202
+ console.log('Write access groups:', permissions.writeGrants.userGroups);
203
+ console.log('Organizations:', permissions.readGrants.organizations);
204
+ ```
205
+
206
+ ### Combining Public and Private Access
207
+
208
+ You can combine public access with specific user/group permissions:
209
+
210
+ ```javascript
211
+ // Make public AND grant write access to specific groups
212
+ await myAgent.publishObject({ save: false });
213
+ await myAgent.grantAccess({
214
+ groupIds: ['grpAdmins'],
215
+ write: true, // Admins can edit
216
+ save: true
217
+ });
218
+
219
+ // Now:
220
+ // - Everyone can read (public_user)
221
+ // - Admins can write (grpAdmins)
222
+ ```
223
+
224
+ ## API Reference
225
+
226
+ ### `publishObject(options)`
227
+
228
+ Publishes or unpublishes an object for public access.
229
+
230
+ **Parameters:**
231
+ - `options` (Object, optional)
232
+ - `publish` (boolean): If true, publishes; if false, unpublishes. Default: `true`
233
+ - `save` (boolean): If true, auto-saves after updating. Default: `true`
234
+
235
+ **Returns:** `Promise<RbtObject>` - The object (saved if `save: true`)
236
+
237
+ **Examples:**
238
+ ```javascript
239
+ // Publish
240
+ await obj.publishObject();
241
+
242
+ // Unpublish
243
+ await obj.publishObject({ publish: false });
244
+
245
+ // Update without saving
246
+ await obj.publishObject({ save: false });
247
+ ```
248
+
249
+ ---
250
+
251
+ ### `unpublishObject(options)`
252
+
253
+ Unpublishes an object to remove public access. This is a convenience method that's equivalent to `publishObject({ publish: false })`.
254
+
255
+ **Parameters:**
256
+ - `options` (Object, optional)
257
+ - `save` (boolean): If true, auto-saves after updating. Default: `true`
258
+
259
+ **Returns:** `Promise<RbtObject>` - The object (saved if `save: true`)
260
+
261
+ **Examples:**
262
+ ```javascript
263
+ // Unpublish (remove public access)
264
+ await obj.unpublishObject();
265
+
266
+ // Unpublish without saving
267
+ await obj.unpublishObject({ save: false });
268
+ ```
269
+
270
+ ---
271
+
272
+ ### `revokeAccess(options)`
273
+
274
+ Revokes access from specific users and/or groups.
275
+
276
+ **Parameters:**
277
+ - `options` (Object, optional)
278
+ - `userIds` (string[]): Array of user IDs to remove from access. Default: `[]`
279
+ - `groupIds` (string[]): Array of group IDs to remove from access. Default: `[]`
280
+ - `write` (boolean): If true, removes write access; if false, removes read access. Default: `false`
281
+ - `save` (boolean): If true, auto-saves after updating. Default: `true`
282
+
283
+ **Returns:** `Promise<RbtObject>` - The object (saved if `save: true`)
284
+
285
+ **Examples:**
286
+ ```javascript
287
+ // Revoke read access from users
288
+ await obj.revokeAccess({ userIds: ['user_123', 'user_456'] });
289
+
290
+ // Revoke write access from groups
291
+ await obj.revokeAccess({ groupIds: ['grpEditors'], write: true });
292
+
293
+ // Revoke from both users and groups
294
+ await obj.revokeAccess({
295
+ userIds: ['user_123'],
296
+ groupIds: ['grpViewers']
297
+ });
298
+
299
+ // Update without saving
300
+ await obj.revokeAccess({ userIds: ['user_123'], save: false });
301
+ ```
302
+
303
+ ---
304
+
305
+ ### `grantAccess(options)`
306
+
307
+ Grants access to this object for specific users and/or groups.
308
+
309
+ **Parameters:**
310
+ - `options` (Object, optional)
311
+ - `userIds` (string[]): Array of user IDs to grant access. Default: `[]`
312
+ - `groupIds` (string[]): Array of group IDs to grant access. Default: `[]`
313
+ - `write` (boolean): If true, grants write access; if false, read access. Default: `false`
314
+ - `replace` (boolean): If true, replaces existing grants; if false, merges. Default: `false`
315
+ - `save` (boolean): If true, auto-saves after updating. Default: `true`
316
+
317
+ **Returns:** `Promise<RbtObject>` - The object (saved if `save: true`)
318
+
319
+ **Examples:**
320
+ ```javascript
321
+ // Grant read access to users
322
+ await obj.grantAccess({ userIds: ['user_123'] });
323
+
324
+ // Grant write access to groups
325
+ await obj.grantAccess({ groupIds: ['grpAdmins'], write: true });
326
+
327
+ // Replace permissions
328
+ await obj.grantAccess({ userIds: ['user_123'], replace: true });
329
+
330
+ // Update without saving
331
+ await obj.grantAccess({ userIds: ['user_123'], save: false });
332
+ ```
333
+
334
+ ---
335
+
336
+ ### `isPublished()`
337
+
338
+ Checks if an object is currently published (publicly accessible).
339
+
340
+ **Returns:** `boolean` - True if public, false otherwise
341
+
342
+ **Example:**
343
+ ```javascript
344
+ if (obj.isPublished()) {
345
+ console.log('Object is public');
346
+ }
347
+ ```
348
+
349
+ ---
350
+
351
+ ### `getSharing()`
352
+
353
+ Gets the current sharing permissions for an object.
354
+
355
+ **Returns:** `Object` - Object containing read and write grants
356
+ - `readGrants` (Object)
357
+ - `users` (string[]): User IDs with read access
358
+ - `userGroups` (string[]): Group IDs with read access
359
+ - `organizations` (string[]): Organization IDs with read access
360
+ - `userSegments` (string[]): Segment IDs with read access
361
+ - `writeGrants` (Object) - Same structure as readGrants
362
+
363
+ **Example:**
364
+ ```javascript
365
+ const perms = obj.getSharing();
366
+ console.log('Read users:', perms.readGrants.users);
367
+ console.log('Write groups:', perms.writeGrants.userGroups);
368
+ ```
369
+
370
+ ## Common Patterns
371
+
372
+ ### Pattern 1: Template Publishing (like Ringable agents)
373
+
374
+ ```javascript
375
+ async function publishTemplate(agent, isPublished) {
376
+ if (isPublished) {
377
+ // Grant access to all account users
378
+ await agent.grantAccess({
379
+ groupIds: ['grpRngAccount']
380
+ });
381
+ } else {
382
+ // Revoke group access
383
+ await agent.revokeAccess({
384
+ groupIds: ['grpRngAccount']
385
+ });
386
+ }
387
+ }
388
+
389
+ // Usage
390
+ await publishTemplate(myAgent, true); // Publish
391
+ await publishTemplate(myAgent, false); // Unpublish
392
+ ```
393
+
394
+ ### Pattern 2: Organization Sharing
395
+
396
+ ```javascript
397
+ async function shareWithOrganization(object, orgId, includeWrite = false) {
398
+ const iac = object.get('iac') || {};
399
+
400
+ // Add to read grants
401
+ if (!iac.readGrants) iac.readGrants = {};
402
+ if (!iac.readGrants.organizations) iac.readGrants.organizations = [];
403
+ if (!iac.readGrants.organizations.includes(orgId)) {
404
+ iac.readGrants.organizations.push(orgId);
405
+ }
406
+
407
+ // Optionally add to write grants
408
+ if (includeWrite) {
409
+ if (!iac.writeGrants) iac.writeGrants = {};
410
+ if (!iac.writeGrants.organizations) iac.writeGrants.organizations = [];
411
+ if (!iac.writeGrants.organizations.includes(orgId)) {
412
+ iac.writeGrants.organizations.push(orgId);
413
+ }
414
+ }
415
+
416
+ object.set('iac', iac);
417
+ return await object.save();
418
+ }
419
+ ```
420
+
421
+ ### Pattern 3: Tiered Access
422
+
423
+ ```javascript
424
+ async function setupTieredAccess(content) {
425
+ // Make public for read
426
+ await content.publishObject({ save: false });
427
+
428
+ // Give write access to editors
429
+ await content.shareObject({
430
+ groupIds: ['grpEditors'],
431
+ write: true,
432
+ save: false
433
+ });
434
+
435
+ // Give admin access
436
+ await content.shareObject({
437
+ groupIds: ['grpAdmins'],
438
+ write: true,
439
+ save: true
440
+ });
441
+
442
+ console.log('Tiered access configured:');
443
+ console.log('- Public: read');
444
+ console.log('- Editors: write');
445
+ console.log('- Admins: write');
446
+ }
447
+ ```
448
+
449
+ ## Important Notes
450
+
451
+ 1. **Permission Propagation**: Changes take effect immediately upon saving. No additional steps required.
452
+
453
+ 2. **Creator Permissions**: The creator always has read and write access by default (managed server-side).
454
+
455
+ 3. **Super Admin Access**: Users in `grpSuperAdmin` have access to all objects regardless of IAC settings.
456
+
457
+ 4. **Array Deduplication**: The methods automatically prevent duplicate entries in permission arrays.
458
+
459
+ 5. **Server-Side Enforcement**: All permissions are enforced server-side. The client methods only update the IAC settings.
460
+
461
+ 6. **Public User**: The special user ID `'public_user'` is assigned to all unauthenticated requests, making any object with `public_user` in readGrants accessible to everyone.
462
+
463
+ ## Quick Reference
464
+
465
+ ```javascript
466
+ // Publishing
467
+ await obj.publishObject(); // Make public
468
+ await obj.unpublishObject(); // Remove public access
469
+ obj.isPublished(); // Check if public
470
+
471
+ // Granting Access
472
+ await obj.grantAccess({ userIds: ['user1', 'user2'] }); // Grant read
473
+ await obj.grantAccess({ groupIds: ['grpA'], write: true }); // Grant write
474
+ await obj.grantAccess({ userIds: ['user1'], replace: true }); // Replace all
475
+
476
+ // Revoking Access
477
+ await obj.revokeAccess({ userIds: ['user1'] }); // Revoke read
478
+ await obj.revokeAccess({ groupIds: ['grpA'], write: true }); // Revoke write
479
+
480
+ // Inspecting
481
+ const perms = obj.getSharing(); // Get all permissions
482
+ ```
483
+