@abraca/dabra 1.0.16 → 1.0.17

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/dist/index.d.ts CHANGED
@@ -371,6 +371,8 @@ declare class AbracadabraClient {
371
371
  doc_type?: string;
372
372
  label?: string;
373
373
  }): Promise<DocumentMeta>;
374
+ /** Broadcast a stateless message to all connected clients on a document (requires manage permission). */
375
+ broadcast(docId: string, payload: string): Promise<void>;
374
376
  /** List all permissions for a document (requires read access). */
375
377
  listPermissions(docId: string): Promise<PermissionEntry[]>;
376
378
  /** List effective permissions including inherited ones from ancestor documents. */
@@ -421,6 +423,26 @@ declare class AbracadabraClient {
421
423
  updateSpace(spaceId: string, opts: Partial<Pick<SpaceMeta, "name" | "description" | "visibility" | "is_hub">>): Promise<SpaceMeta>;
422
424
  /** Delete a space and its root document (Owner or admin required). */
423
425
  deleteSpace(spaceId: string): Promise<void>;
426
+ /** List all users (requires elevated role: admin or service). */
427
+ adminListUsers(): Promise<{
428
+ users: (UserProfile & {
429
+ revoked: boolean;
430
+ deviceKeys: string[];
431
+ })[];
432
+ }>;
433
+ /** Promote a user to admin (requires service role). */
434
+ adminPromote(userId: string): Promise<void>;
435
+ /** Demote an admin user back to regular (requires service role). */
436
+ adminDemote(userId: string): Promise<void>;
437
+ /** Sweep orphaned file blobs from storage (requires elevated role). */
438
+ adminStorageSweep(): Promise<{
439
+ blobsDeleted: number;
440
+ }>;
441
+ /** Repair blob ref-counts and sweep orphans (requires elevated role). */
442
+ adminStorageRepair(): Promise<{
443
+ refCountsRepaired: number;
444
+ blobsSwept: number;
445
+ }>;
424
446
  /** Health check — no auth required. */
425
447
  health(): Promise<HealthStatus>;
426
448
  /**
@@ -645,6 +667,7 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
645
667
  private handleAuthChallenge;
646
668
  private restorePermissionSnapshot;
647
669
  get canWrite(): boolean;
670
+ get canAwareness(): boolean;
648
671
  /** The AbracadabraClient instance for REST API access, if configured. */
649
672
  get client(): AbracadabraClient | null;
650
673
  /** The OfflineStore instance, or null if offline storage is disabled. */
@@ -864,7 +887,7 @@ declare enum WebSocketStatus {
864
887
  Connected = "connected",
865
888
  Disconnected = "disconnected"
866
889
  }
867
- type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "read-write" | "readonly";
890
+ type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "observer" | "read-write" | "readonly";
868
891
  interface OutgoingMessageInterface {
869
892
  encoder: Encoder;
870
893
  type?: MessageType;
@@ -930,7 +953,7 @@ type StatesArray = {
930
953
  clientId: number;
931
954
  [key: string | number]: any;
932
955
  }[];
933
- type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | null;
956
+ type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | "observer" | null;
934
957
  /**
935
958
  * Ed25519 identity for passwordless crypto auth.
936
959
  *
@@ -966,6 +989,8 @@ interface UserProfile {
966
989
  interface DocumentMeta {
967
990
  id: string;
968
991
  parent_id: string | null;
992
+ doc_type?: string | null;
993
+ label?: string | null;
969
994
  }
970
995
  interface UploadMeta {
971
996
  id: string;
@@ -986,13 +1011,13 @@ interface PublicKeyInfo {
986
1011
  }
987
1012
  interface PermissionEntry {
988
1013
  user_id: string;
989
- role: "owner" | "editor" | "viewer" | "observer";
1014
+ role: "service" | "admin" | "owner" | "editor" | "viewer" | "observer";
990
1015
  username: string;
991
1016
  display_name: string | null;
992
1017
  }
993
1018
  interface EffectivePermissionEntry {
994
1019
  user_id: string;
995
- role: "owner" | "editor" | "viewer" | "observer";
1020
+ role: "service" | "admin" | "owner" | "editor" | "viewer" | "observer";
996
1021
  username: string;
997
1022
  display_name: string | null;
998
1023
  source: "direct" | "inherited";
@@ -1012,10 +1037,23 @@ interface ServerInfo {
1012
1037
  name?: string;
1013
1038
  /** Server version string. */
1014
1039
  version?: string;
1040
+ /** Hocuspocus wire protocol version (currently 2). */
1041
+ protocol_version?: number;
1015
1042
  /** Entry-point document ID advertised by the server, if configured. */
1016
1043
  index_doc_id?: string;
1017
1044
  /** Default role assigned to users without explicit permissions. */
1018
1045
  default_role?: string;
1046
+ /** Enabled auth methods (e.g. ["crypto", "jwt"]). */
1047
+ auth_methods?: string[];
1048
+ /** Whether open registration is enabled. */
1049
+ registration_allowed?: boolean;
1050
+ /** Whether an invite code is required to register. */
1051
+ invite_only?: boolean;
1052
+ /** Server encryption configuration. */
1053
+ encryption?: {
1054
+ default_mode?: string;
1055
+ minimum_mode?: string;
1056
+ };
1019
1057
  }
1020
1058
  interface SearchResult {
1021
1059
  docId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -336,6 +336,11 @@ export class AbracadabraClient {
336
336
  );
337
337
  }
338
338
 
339
+ /** Broadcast a stateless message to all connected clients on a document (requires manage permission). */
340
+ async broadcast(docId: string, payload: string): Promise<void> {
341
+ await this.request("POST", `/docs/${encodeURIComponent(docId)}/broadcast`, { body: { payload } });
342
+ }
343
+
339
344
  // ── Permissions ──────────────────────────────────────────────────────────
340
345
 
341
346
  /** List all permissions for a document (requires read access). */
@@ -535,6 +540,33 @@ export class AbracadabraClient {
535
540
  await this.request("DELETE", `/spaces/${encodeURIComponent(spaceId)}`);
536
541
  }
537
542
 
543
+ // ── Admin ───────────────────────────────────────────────────────────────
544
+
545
+ /** List all users (requires elevated role: admin or service). */
546
+ async adminListUsers(): Promise<{ users: (UserProfile & { revoked: boolean; deviceKeys: string[] })[] }> {
547
+ return this.request("GET", "/admin/users");
548
+ }
549
+
550
+ /** Promote a user to admin (requires service role). */
551
+ async adminPromote(userId: string): Promise<void> {
552
+ await this.request("POST", `/admin/users/${encodeURIComponent(userId)}/admin`);
553
+ }
554
+
555
+ /** Demote an admin user back to regular (requires service role). */
556
+ async adminDemote(userId: string): Promise<void> {
557
+ await this.request("DELETE", `/admin/users/${encodeURIComponent(userId)}/admin`);
558
+ }
559
+
560
+ /** Sweep orphaned file blobs from storage (requires elevated role). */
561
+ async adminStorageSweep(): Promise<{ blobsDeleted: number }> {
562
+ return this.request("POST", "/admin/storage/sweep");
563
+ }
564
+
565
+ /** Repair blob ref-counts and sweep orphans (requires elevated role). */
566
+ async adminStorageRepair(): Promise<{ refCountsRepaired: number; blobsSwept: number }> {
567
+ return this.request("POST", "/admin/storage/repair");
568
+ }
569
+
538
570
  // ── System ───────────────────────────────────────────────────────────────
539
571
 
540
572
  /** Health check — no auth required. */
@@ -226,10 +226,11 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
226
226
  owner: "owner",
227
227
  editor: "editor",
228
228
  viewer: "viewer",
229
+ observer: "observer",
229
230
  "read-write": "editor",
230
231
  readonly: "viewer",
231
232
  };
232
- this.effectiveRole = roleMap[scope] ?? "viewer";
233
+ this.effectiveRole = roleMap[scope] ?? "observer";
233
234
 
234
235
  this.offlineStore?.savePermissionSnapshot(this.effectiveRole);
235
236
  }
@@ -303,7 +304,11 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
303
304
  }
304
305
 
305
306
  get canWrite(): boolean {
306
- return this.effectiveRole != null && this.effectiveRole !== "viewer";
307
+ return this.effectiveRole != null && this.effectiveRole !== "viewer" && this.effectiveRole !== "observer";
308
+ }
309
+
310
+ get canAwareness(): boolean {
311
+ return this.effectiveRole != null && this.effectiveRole !== "observer";
307
312
  }
308
313
 
309
314
  /** The AbracadabraClient instance for REST API access, if configured. */
package/src/types.ts CHANGED
@@ -40,7 +40,7 @@ export enum WebSocketStatus {
40
40
  Disconnected = "disconnected",
41
41
  }
42
42
 
43
- export type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "read-write" | "readonly";
43
+ export type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "observer" | "read-write" | "readonly";
44
44
 
45
45
  export interface OutgoingMessageInterface {
46
46
  encoder: Encoder;
@@ -128,7 +128,7 @@ export type StatesArray = { clientId: number; [key: string | number]: any }[];
128
128
 
129
129
  // ── Abracadabra extensions ────────────────────────────────────────────────────
130
130
 
131
- export type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | null;
131
+ export type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | "observer" | null;
132
132
 
133
133
  /**
134
134
  * Ed25519 identity for passwordless crypto auth.
@@ -173,6 +173,8 @@ export interface UserProfile {
173
173
  export interface DocumentMeta {
174
174
  id: string;
175
175
  parent_id: string | null;
176
+ doc_type?: string | null;
177
+ label?: string | null;
176
178
  }
177
179
 
178
180
  export interface UploadMeta {
@@ -197,14 +199,14 @@ export interface PublicKeyInfo {
197
199
 
198
200
  export interface PermissionEntry {
199
201
  user_id: string;
200
- role: "owner" | "editor" | "viewer" | "observer";
202
+ role: "service" | "admin" | "owner" | "editor" | "viewer" | "observer";
201
203
  username: string;
202
204
  display_name: string | null;
203
205
  }
204
206
 
205
207
  export interface EffectivePermissionEntry {
206
208
  user_id: string;
207
- role: "owner" | "editor" | "viewer" | "observer";
209
+ role: "service" | "admin" | "owner" | "editor" | "viewer" | "observer";
208
210
  username: string;
209
211
  display_name: string | null;
210
212
  source: "direct" | "inherited";
@@ -227,10 +229,20 @@ export interface ServerInfo {
227
229
  name?: string;
228
230
  /** Server version string. */
229
231
  version?: string;
232
+ /** Hocuspocus wire protocol version (currently 2). */
233
+ protocol_version?: number;
230
234
  /** Entry-point document ID advertised by the server, if configured. */
231
235
  index_doc_id?: string;
232
236
  /** Default role assigned to users without explicit permissions. */
233
237
  default_role?: string;
238
+ /** Enabled auth methods (e.g. ["crypto", "jwt"]). */
239
+ auth_methods?: string[];
240
+ /** Whether open registration is enabled. */
241
+ registration_allowed?: boolean;
242
+ /** Whether an invite code is required to register. */
243
+ invite_only?: boolean;
244
+ /** Server encryption configuration. */
245
+ encryption?: { default_mode?: string; minimum_mode?: string };
234
246
  }
235
247
 
236
248
  // ── Search ───────────────────────────────────────────────────────────────────