@abraca/dabra 0.7.0 → 0.9.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.
package/dist/index.d.ts CHANGED
@@ -206,6 +206,7 @@ declare class AbracadabraClient {
206
206
  password: string;
207
207
  email?: string;
208
208
  displayName?: string;
209
+ inviteCode?: string;
209
210
  }): Promise<UserProfile>;
210
211
  /**
211
212
  * Register a new user with an Ed25519 public key (crypto auth).
@@ -217,6 +218,7 @@ declare class AbracadabraClient {
217
218
  deviceName?: string;
218
219
  displayName?: string;
219
220
  email?: string;
221
+ inviteCode?: string;
220
222
  }): Promise<UserProfile>;
221
223
  /** Login with username + password. Auto-persists returned token. */
222
224
  login(opts: {
@@ -289,6 +291,18 @@ declare class AbracadabraClient {
289
291
  getUpload(docId: string, uploadId: string): Promise<Blob>;
290
292
  /** Delete an upload (requires uploader or document Owner). */
291
293
  deleteUpload(docId: string, uploadId: string): Promise<void>;
294
+ /** Create an invite code (requires permission per server config). */
295
+ createInvite(opts?: {
296
+ role?: string;
297
+ maxUses?: number;
298
+ expiresIn?: number;
299
+ }): Promise<InviteRow>;
300
+ /** List invite codes visible to the current user. */
301
+ listInvites(): Promise<InviteRow[]>;
302
+ /** Revoke an invite by its code. */
303
+ revokeInvite(code: string): Promise<void>;
304
+ /** Redeem an invite code for the currently authenticated user. */
305
+ redeemInvite(code: string): Promise<void>;
292
306
  /** Health check — no auth required. */
293
307
  health(): Promise<HealthStatus>;
294
308
  /**
@@ -622,7 +636,7 @@ declare enum WebSocketStatus {
622
636
  Connected = "connected",
623
637
  Disconnected = "disconnected"
624
638
  }
625
- type AuthorizedScope = "read-write" | "readonly";
639
+ type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "read-write" | "readonly";
626
640
  interface OutgoingMessageInterface {
627
641
  encoder: Encoder;
628
642
  type?: MessageType;
@@ -688,7 +702,7 @@ type StatesArray = {
688
702
  clientId: number;
689
703
  [key: string | number]: any;
690
704
  }[];
691
- type EffectiveRole = "owner" | "editor" | "viewer" | null;
705
+ type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | null;
692
706
  /**
693
707
  * Ed25519 identity for passwordless crypto auth.
694
708
  *
@@ -717,6 +731,7 @@ interface UserProfile {
717
731
  username: string;
718
732
  email: string | null;
719
733
  displayName: string | null;
734
+ role: string;
720
735
  }
721
736
  interface DocumentMeta {
722
737
  id: string;
@@ -763,6 +778,16 @@ interface SearchResult {
763
778
  /** Number of matching trigrams — higher is better. */
764
779
  score: number;
765
780
  }
781
+ interface InviteRow {
782
+ code: string;
783
+ createdBy: string | null;
784
+ role: string;
785
+ maxUses: number;
786
+ useCount: number;
787
+ expiresAt: number | null;
788
+ revoked: boolean;
789
+ createdAt: number;
790
+ }
766
791
  type UploadQueueStatus = "pending" | "uploading" | "done" | "error";
767
792
  interface UploadQueueEntry {
768
793
  /** Client-generated UUID. */
@@ -1243,4 +1268,4 @@ declare class FileBlobStore extends EventEmitter {
1243
1268
  destroy(): void;
1244
1269
  }
1245
1270
  //#endregion
1246
- export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, CryptoIdentity, CryptoIdentityKeystore, DocumentCache, type DocumentCacheOptions, DocumentMeta, EffectiveRole, FileBlobStore, Forbidden, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, MessageTooBig, MessageType, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, ServerInfo, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, awarenessStatesToArray, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
1271
+ export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, CryptoIdentity, CryptoIdentityKeystore, DocumentCache, type DocumentCacheOptions, DocumentMeta, EffectiveRole, FileBlobStore, Forbidden, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, InviteRow, MessageTooBig, MessageType, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, ServerInfo, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, awarenessStatesToArray, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -7,6 +7,7 @@ import type {
7
7
  PermissionEntry,
8
8
  HealthStatus,
9
9
  ServerInfo,
10
+ InviteRow,
10
11
  } from "./types.ts";
11
12
  import type { DocumentCache } from "./DocumentCache.ts";
12
13
 
@@ -85,6 +86,7 @@ export class AbracadabraClient {
85
86
  password: string;
86
87
  email?: string;
87
88
  displayName?: string;
89
+ inviteCode?: string;
88
90
  }): Promise<UserProfile> {
89
91
  return this.request<UserProfile>("POST", "/auth/register", {
90
92
  body: opts,
@@ -102,6 +104,7 @@ export class AbracadabraClient {
102
104
  deviceName?: string;
103
105
  displayName?: string;
104
106
  email?: string;
107
+ inviteCode?: string;
105
108
  }): Promise<UserProfile> {
106
109
  const username = opts.username ?? `user-${opts.publicKey.slice(0, 8)}`;
107
110
  return this.request<UserProfile>("POST", "/auth/register", {
@@ -111,6 +114,7 @@ export class AbracadabraClient {
111
114
  deviceName: opts.deviceName,
112
115
  displayName: opts.displayName,
113
116
  email: opts.email,
117
+ inviteCode: opts.inviteCode,
114
118
  },
115
119
  auth: false,
116
120
  });
@@ -368,6 +372,29 @@ export class AbracadabraClient {
368
372
  }
369
373
  }
370
374
 
375
+ // ── Invites ──────────────────────────────────────────────────────────────
376
+
377
+ /** Create an invite code (requires permission per server config). */
378
+ async createInvite(opts?: { role?: string; maxUses?: number; expiresIn?: number }): Promise<InviteRow> {
379
+ return this.request<InviteRow>("POST", "/invites", { body: opts ?? {} });
380
+ }
381
+
382
+ /** List invite codes visible to the current user. */
383
+ async listInvites(): Promise<InviteRow[]> {
384
+ const res = await this.request<{ invites: InviteRow[] }>("GET", "/invites");
385
+ return res.invites;
386
+ }
387
+
388
+ /** Revoke an invite by its code. */
389
+ async revokeInvite(code: string): Promise<void> {
390
+ await this.request("DELETE", `/invites/${encodeURIComponent(code)}`);
391
+ }
392
+
393
+ /** Redeem an invite code for the currently authenticated user. */
394
+ async redeemInvite(code: string): Promise<void> {
395
+ await this.request("POST", "/invites/redeem", { body: { code } });
396
+ }
397
+
371
398
  // ── System ───────────────────────────────────────────────────────────────
372
399
 
373
400
  /** Health check — no auth required. */
@@ -208,8 +208,16 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
208
208
  override authenticatedHandler(scope: string) {
209
209
  super.authenticatedHandler(scope);
210
210
 
211
- this.effectiveRole =
212
- scope === "read-write" ? "editor" : "viewer";
211
+ const roleMap: Record<string, import("./types.ts").EffectiveRole> = {
212
+ service: "service",
213
+ admin: "admin",
214
+ owner: "owner",
215
+ editor: "editor",
216
+ viewer: "viewer",
217
+ "read-write": "editor",
218
+ readonly: "viewer",
219
+ };
220
+ this.effectiveRole = roleMap[scope] ?? "viewer";
213
221
 
214
222
  this.offlineStore?.savePermissionSnapshot(this.effectiveRole);
215
223
  }
@@ -283,7 +291,7 @@ export class AbracadabraProvider extends AbracadabraBaseProvider {
283
291
  }
284
292
 
285
293
  get canWrite(): boolean {
286
- return this.effectiveRole === "owner" || this.effectiveRole === "editor";
294
+ return this.effectiveRole != null && this.effectiveRole !== "viewer";
287
295
  }
288
296
 
289
297
  /** 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 = "read-write" | "readonly";
43
+ export type AuthorizedScope = "service" | "admin" | "owner" | "editor" | "viewer" | "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 = "owner" | "editor" | "viewer" | null;
131
+ export type EffectiveRole = "service" | "admin" | "owner" | "editor" | "viewer" | null;
132
132
 
133
133
  /**
134
134
  * Ed25519 identity for passwordless crypto auth.
@@ -165,6 +165,7 @@ export interface UserProfile {
165
165
  username: string;
166
166
  email: string | null;
167
167
  displayName: string | null;
168
+ role: string;
168
169
  }
169
170
 
170
171
  export interface DocumentMeta {
@@ -222,6 +223,19 @@ export interface SearchResult {
222
223
  score: number;
223
224
  }
224
225
 
226
+ // ── Invites ──────────────────────────────────────────────────────────────────
227
+
228
+ export interface InviteRow {
229
+ code: string;
230
+ createdBy: string | null;
231
+ role: string;
232
+ maxUses: number;
233
+ useCount: number;
234
+ expiresAt: number | null;
235
+ revoked: boolean;
236
+ createdAt: number;
237
+ }
238
+
225
239
  // ── Upload queue ─────────────────────────────────────────────────────────────
226
240
 
227
241
  export type UploadQueueStatus = "pending" | "uploading" | "done" | "error";