@abraca/dabra 2.21.0 → 2.22.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.
@@ -10515,6 +10515,20 @@ var IdentityDocProvider = class extends EventEmitter {
10515
10515
  function fromBase64$3(b64) {
10516
10516
  return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
10517
10517
  }
10518
+ /**
10519
+ * Decode a base64url-encoded string (e.g. a JWT header/payload segment) to
10520
+ * UTF-8 text. `atob` only accepts standard base64, so we translate the
10521
+ * url-safe alphabet (`-`/`_`) and re-pad before decoding — otherwise a
10522
+ * perfectly valid token whose payload happens to contain `-` or `_` throws
10523
+ * and gets misclassified as invalid/expired.
10524
+ */
10525
+ function decodeBase64UrlToString(b64url) {
10526
+ let b64 = b64url.replace(/-/g, "+").replace(/_/g, "/");
10527
+ const pad = b64.length % 4;
10528
+ if (pad) b64 += "=".repeat(4 - pad);
10529
+ const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
10530
+ return new TextDecoder().decode(bytes);
10531
+ }
10518
10532
  var AbracadabraClient = class {
10519
10533
  constructor(config) {
10520
10534
  this.rootListInflight = /* @__PURE__ */ new Map();
@@ -10542,7 +10556,7 @@ var AbracadabraClient = class {
10542
10556
  if (!this._token) return false;
10543
10557
  try {
10544
10558
  const [, payload] = this._token.split(".");
10545
- const { exp } = JSON.parse(atob(payload));
10559
+ const { exp } = JSON.parse(decodeBase64UrlToString(payload));
10546
10560
  return typeof exp === "number" && exp * 1e3 > Date.now();
10547
10561
  } catch {
10548
10562
  return false;
@@ -10632,9 +10646,17 @@ var AbracadabraClient = class {
10632
10646
  async renameKey(keyId, deviceName) {
10633
10647
  await this.request("PATCH", `/auth/keys/${encodeURIComponent(keyId)}`, { body: { deviceName } });
10634
10648
  }
10635
- /** Revoke a public key by its ID. */
10649
+ /**
10650
+ * Revoke a public key by its ID. The server treats this as a panic
10651
+ * action: every outstanding JWT for the account is invalidated (a stolen
10652
+ * device's token must die immediately, and tokens carry no per-key
10653
+ * claim), and a fresh token for THIS session is returned and adopted
10654
+ * automatically — so the device performing the revocation stays
10655
+ * authenticated while every other device silently re-auths.
10656
+ */
10636
10657
  async revokeKey(keyId) {
10637
- await this.request("DELETE", `/auth/keys/${encodeURIComponent(keyId)}`);
10658
+ const res = await this.request("DELETE", `/auth/keys/${encodeURIComponent(keyId)}`);
10659
+ if (res && typeof res === "object" && typeof res.token === "string") this.token = res.token;
10638
10660
  }
10639
10661
  /** Create a single-use device invite code for pairing a new device to this account. */
10640
10662
  async createDeviceInvite(opts) {
@@ -11764,7 +11786,11 @@ var TokenManager = class extends EventEmitter {
11764
11786
  try {
11765
11787
  const [, payload] = jwt.split(".");
11766
11788
  if (!payload) return null;
11767
- const { exp } = JSON.parse(atob(payload));
11789
+ let b64 = payload.replace(/-/g, "+").replace(/_/g, "/");
11790
+ const pad = b64.length % 4;
11791
+ if (pad) b64 += "=".repeat(4 - pad);
11792
+ const json = new TextDecoder().decode(Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)));
11793
+ const { exp } = JSON.parse(json);
11768
11794
  return typeof exp === "number" ? exp : null;
11769
11795
  } catch {
11770
11796
  return null;
@@ -15244,7 +15270,10 @@ var FileBlobStore = class FileBlobStore extends EventEmitter {
15244
15270
  */
15245
15271
  const HKDF_INFO = new TextEncoder().encode("abracadabra-dockey-v1");
15246
15272
  function fromBase64$2(b64) {
15247
- return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
15273
+ let normalized = b64.replace(/-/g, "+").replace(/_/g, "/");
15274
+ const pad = normalized.length % 4;
15275
+ if (pad) normalized += "=".repeat(4 - pad);
15276
+ return Uint8Array.from(atob(normalized), (c) => c.charCodeAt(0));
15248
15277
  }
15249
15278
  var DocKeyManager = class DocKeyManager {
15250
15279
  constructor() {
@@ -15301,7 +15330,7 @@ var DocKeyManager = class DocKeyManager {
15301
15330
  if (me.publicKey) {
15302
15331
  const primaryKey = (await client.listUserKeys(me.id))[0];
15303
15332
  if (primaryKey?.x25519Key) {
15304
- const x25519Pub = fromBase64$2(primaryKey.x25519Key.replace(/-/g, "+").replace(/_/g, "/"));
15333
+ const x25519Pub = fromBase64$2(primaryKey.x25519Key);
15305
15334
  const rewrapped = await this.wrapKeyForRecipient(docKey, x25519Pub, docId);
15306
15335
  const b64 = (() => {
15307
15336
  let s = "";