@abraca/dabra 2.21.0 → 2.23.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.
@@ -10485,6 +10485,20 @@ var IdentityDocProvider = class extends EventEmitter {
10485
10485
  function fromBase64$3(b64) {
10486
10486
  return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
10487
10487
  }
10488
+ /**
10489
+ * Decode a base64url-encoded string (e.g. a JWT header/payload segment) to
10490
+ * UTF-8 text. `atob` only accepts standard base64, so we translate the
10491
+ * url-safe alphabet (`-`/`_`) and re-pad before decoding — otherwise a
10492
+ * perfectly valid token whose payload happens to contain `-` or `_` throws
10493
+ * and gets misclassified as invalid/expired.
10494
+ */
10495
+ function decodeBase64UrlToString(b64url) {
10496
+ let b64 = b64url.replace(/-/g, "+").replace(/_/g, "/");
10497
+ const pad = b64.length % 4;
10498
+ if (pad) b64 += "=".repeat(4 - pad);
10499
+ const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
10500
+ return new TextDecoder().decode(bytes);
10501
+ }
10488
10502
  var AbracadabraClient = class {
10489
10503
  constructor(config) {
10490
10504
  this.rootListInflight = /* @__PURE__ */ new Map();
@@ -10512,7 +10526,7 @@ var AbracadabraClient = class {
10512
10526
  if (!this._token) return false;
10513
10527
  try {
10514
10528
  const [, payload] = this._token.split(".");
10515
- const { exp } = JSON.parse(atob(payload));
10529
+ const { exp } = JSON.parse(decodeBase64UrlToString(payload));
10516
10530
  return typeof exp === "number" && exp * 1e3 > Date.now();
10517
10531
  } catch {
10518
10532
  return false;
@@ -10602,9 +10616,17 @@ var AbracadabraClient = class {
10602
10616
  async renameKey(keyId, deviceName) {
10603
10617
  await this.request("PATCH", `/auth/keys/${encodeURIComponent(keyId)}`, { body: { deviceName } });
10604
10618
  }
10605
- /** Revoke a public key by its ID. */
10619
+ /**
10620
+ * Revoke a public key by its ID. The server treats this as a panic
10621
+ * action: every outstanding JWT for the account is invalidated (a stolen
10622
+ * device's token must die immediately, and tokens carry no per-key
10623
+ * claim), and a fresh token for THIS session is returned and adopted
10624
+ * automatically — so the device performing the revocation stays
10625
+ * authenticated while every other device silently re-auths.
10626
+ */
10606
10627
  async revokeKey(keyId) {
10607
- await this.request("DELETE", `/auth/keys/${encodeURIComponent(keyId)}`);
10628
+ const res = await this.request("DELETE", `/auth/keys/${encodeURIComponent(keyId)}`);
10629
+ if (res && typeof res === "object" && typeof res.token === "string") this.token = res.token;
10608
10630
  }
10609
10631
  /** Create a single-use device invite code for pairing a new device to this account. */
10610
10632
  async createDeviceInvite(opts) {
@@ -11734,7 +11756,11 @@ var TokenManager = class extends EventEmitter {
11734
11756
  try {
11735
11757
  const [, payload] = jwt.split(".");
11736
11758
  if (!payload) return null;
11737
- const { exp } = JSON.parse(atob(payload));
11759
+ let b64 = payload.replace(/-/g, "+").replace(/_/g, "/");
11760
+ const pad = b64.length % 4;
11761
+ if (pad) b64 += "=".repeat(4 - pad);
11762
+ const json = new TextDecoder().decode(Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)));
11763
+ const { exp } = JSON.parse(json);
11738
11764
  return typeof exp === "number" ? exp : null;
11739
11765
  } catch {
11740
11766
  return null;
@@ -15214,7 +15240,10 @@ var FileBlobStore = class FileBlobStore extends EventEmitter {
15214
15240
  */
15215
15241
  const HKDF_INFO = new TextEncoder().encode("abracadabra-dockey-v1");
15216
15242
  function fromBase64$2(b64) {
15217
- return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
15243
+ let normalized = b64.replace(/-/g, "+").replace(/_/g, "/");
15244
+ const pad = normalized.length % 4;
15245
+ if (pad) normalized += "=".repeat(4 - pad);
15246
+ return Uint8Array.from(atob(normalized), (c) => c.charCodeAt(0));
15218
15247
  }
15219
15248
  var DocKeyManager = class DocKeyManager {
15220
15249
  constructor() {
@@ -15271,7 +15300,7 @@ var DocKeyManager = class DocKeyManager {
15271
15300
  if (me.publicKey) {
15272
15301
  const primaryKey = (await client.listUserKeys(me.id))[0];
15273
15302
  if (primaryKey?.x25519Key) {
15274
- const x25519Pub = fromBase64$2(primaryKey.x25519Key.replace(/-/g, "+").replace(/_/g, "/"));
15303
+ const x25519Pub = fromBase64$2(primaryKey.x25519Key);
15275
15304
  const rewrapped = await this.wrapKeyForRecipient(docKey, x25519Pub, docId);
15276
15305
  const b64 = (() => {
15277
15306
  let s = "";