@glyphteck/veyl 0.66.3 → 0.68.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.
@@ -115,6 +115,7 @@ var CHAT_MANIFEST_MAX_BYTES = 256 * KIB_BYTES;
115
115
  var CHAT_RECEIPT_MAX_MEMBERS = 32;
116
116
  var CHAT_ORDINARY_DELIVERY_MAX_MEMBERS = 128;
117
117
  var CHAT_MAX_MEMBERS = 256;
118
+ var CHAT_LARGE_GROUP_MENTION_MAX_TARGETS = 16;
118
119
  var CHAT_MAX_TEXT_CHARS = 2048;
119
120
  var CHAT_TITLE_INPUT_MAX_CHARS = 16;
120
121
  var CHAT_MAX_REACTIONS = CHAT_MAX_MEMBERS;
@@ -249,6 +250,57 @@ function cleanBytes(...values) {
249
250
  }
250
251
  }
251
252
 
253
+ // ../../core/passkey.js
254
+ var PASSKEY_ENVIRONMENT_MISMATCH = "passkey-environment-mismatch";
255
+ var PASSKEY_PROVIDER_ALREADY_LINKED = "passkey-provider-already-linked";
256
+ var PASSKEY_REGISTER_INVALID = "passkey-register-invalid";
257
+ var PASSKEY_RP_MISMATCH = "passkey-rp-mismatch";
258
+ var PASSKEY_UNLINKED = "passkey-unlinked";
259
+ var PASSKEY_CANCELLED_CODES = new Set(["ERR_USER_CANCELLED"]);
260
+ var PASSKEY_CANCELLED_NAMES = new Set(["UserCancelledException"]);
261
+ var PASSKEY_CONTROLLED_ERRORS = new Set([
262
+ PASSKEY_ENVIRONMENT_MISMATCH,
263
+ PASSKEY_PROVIDER_ALREADY_LINKED,
264
+ PASSKEY_REGISTER_INVALID,
265
+ PASSKEY_RP_MISMATCH,
266
+ PASSKEY_UNLINKED
267
+ ]);
268
+ function canDeletePasskey(row, passkeys, currentPasskeyId) {
269
+ if (row?.type === "pending")
270
+ return true;
271
+ return row?.type === "passkey" && Array.isArray(passkeys) && passkeys.length > 1 && row.id !== cleanText(currentPasskeyId);
272
+ }
273
+ function passkeyError(code, message, cause) {
274
+ const error = new Error(message);
275
+ error.code = code;
276
+ error.cause = cause;
277
+ return error;
278
+ }
279
+ function normalizePasskeyLoginError(error, options = {}) {
280
+ if (options.localhostSilo === true && error?.code === "functions/failed-precondition" && cleanText(error?.message).includes("Localhost uses a separate passkey silo")) {
281
+ return passkeyError(PASSKEY_ENVIRONMENT_MISMATCH, "This passkey belongs to glyphteck.com, not localhost.", error);
282
+ }
283
+ if (error?.code === "functions/not-found") {
284
+ return passkeyError(PASSKEY_UNLINKED, "This passkey is no longer linked to an account.", error);
285
+ }
286
+ if (error?.code === "functions/failed-precondition") {
287
+ return passkeyError(PASSKEY_RP_MISMATCH, "This passkey belongs to a different Glyphteck passkey setup.", error);
288
+ }
289
+ return error;
290
+ }
291
+ function normalizePasskeyRegisterError(error, options = {}) {
292
+ if (error?.name === "CredentialAlreadyExistsException" || error?.name === "InvalidStateError" || error?.code === "functions/already-exists") {
293
+ return passkeyError(PASSKEY_PROVIDER_ALREADY_LINKED, "you already have a passkey for this account", error);
294
+ }
295
+ if (error?.code === "functions/failed-precondition") {
296
+ return passkeyError(PASSKEY_RP_MISMATCH, "This passkey belongs to a different Glyphteck passkey setup.", error);
297
+ }
298
+ if (options.invalidArgument === true && error?.code === "functions/invalid-argument" && error?.message) {
299
+ return passkeyError(PASSKEY_REGISTER_INVALID, error.message, error);
300
+ }
301
+ return error;
302
+ }
303
+
252
304
  // ../../core/account/profiles.js
253
305
  var ACCOUNT_PROFILES_VERSION = 1;
254
306
  var PROFILE_ID_RE = /^[0-9a-f]{32}$/;
@@ -512,6 +564,71 @@ function deselectAccountProfile(value, profileId) {
512
564
  return freezeRegistry({ ...registry, selectedProfileId: null });
513
565
  }
514
566
 
567
+ // ../../core/account/scope.js
568
+ var ACCOUNT_SCOPE_STALE_CODE = "account-scope/stale";
569
+ var PROFILE_ID_RE2 = /^[0-9a-f]{32}$/;
570
+ var ACCOUNT_SCOPE_CAPABILITIES = new WeakSet;
571
+ function requireGeneration(value) {
572
+ const generation = Number(value);
573
+ if (!Number.isSafeInteger(generation) || generation < 0) {
574
+ throw new Error("account scope generation required");
575
+ }
576
+ return generation;
577
+ }
578
+ function requireProfileId(value) {
579
+ const profileId = lowerText(value);
580
+ if (!PROFILE_ID_RE2.test(profileId))
581
+ throw new Error("account scope profile id required");
582
+ return profileId;
583
+ }
584
+ function requireText(value, label) {
585
+ const text = cleanText(value);
586
+ if (!text)
587
+ throw new Error(`${label} required`);
588
+ return text;
589
+ }
590
+ function staleAccountScopeError(scope = null) {
591
+ const error = new Error("account scope is no longer active");
592
+ error.code = ACCOUNT_SCOPE_STALE_CODE;
593
+ error.profileId = scope?.profileId || null;
594
+ error.generation = Number.isSafeInteger(scope?.generation) ? scope.generation : null;
595
+ return error;
596
+ }
597
+ function createAccountScope({
598
+ environment,
599
+ generation,
600
+ isCurrent,
601
+ profileId,
602
+ uid
603
+ } = {}) {
604
+ if (typeof isCurrent !== "function")
605
+ throw new Error("account scope current-state port required");
606
+ const normalizedEnvironment = lowerText(requireText(environment, "account scope environment"));
607
+ const normalizedGeneration = requireGeneration(generation);
608
+ const normalizedProfileId = requireProfileId(profileId);
609
+ const normalizedUid = requireText(uid, "account scope uid");
610
+ const accountOwnerKey = `${normalizedEnvironment}:${normalizedProfileId}:${normalizedUid}`;
611
+ const scope = {
612
+ accountOwnerKey,
613
+ environment: normalizedEnvironment,
614
+ generation: normalizedGeneration,
615
+ key: `${accountOwnerKey}:${normalizedGeneration}`,
616
+ profileId: normalizedProfileId,
617
+ uid: normalizedUid,
618
+ isCurrent: () => isCurrent() === true,
619
+ assertCurrent() {
620
+ if (!scope.isCurrent())
621
+ throw staleAccountScopeError(scope);
622
+ return scope;
623
+ }
624
+ };
625
+ ACCOUNT_SCOPE_CAPABILITIES.add(scope);
626
+ return Object.freeze(scope);
627
+ }
628
+ function isAccountScope(value) {
629
+ return !!value && typeof value === "object" && ACCOUNT_SCOPE_CAPABILITIES.has(value);
630
+ }
631
+
515
632
  // src/accountprofiles.js
516
633
  var ACCOUNT_PROFILE_STALE_CODE = "account-profiles/stale";
517
634
  var ACCOUNT_PROFILE_AUTH_REQUIRED_CODE = "account-profiles/auth-required";
@@ -606,7 +723,7 @@ function requirePorts(options) {
606
723
  onError: typeof options.onError === "function" ? options.onError : null
607
724
  };
608
725
  }
609
- async function resolveAuthenticatedProfile(owner, generation, reason) {
726
+ async function resolveAuthenticatedProfile(owner, generation, reason, details = {}) {
610
727
  ensureGeneration(owner, generation);
611
728
  const registry = owner.registry;
612
729
  const context = Object.freeze({
@@ -614,6 +731,7 @@ async function resolveAuthenticatedProfile(owner, generation, reason) {
614
731
  generation,
615
732
  reason,
616
733
  requestedProfileId: owner.requestedProfileId,
734
+ rejectedProfileId: details.rejectedProfileId || null,
617
735
  isCurrent: () => !owner.closing && !owner.closed && owner.generation === generation
618
736
  });
619
737
  const profileId = await owner.ports.resolveAuthenticatedProfile(registry, context);
@@ -626,12 +744,16 @@ async function resolveAuthenticatedProfile(owner, generation, reason) {
626
744
  return profile;
627
745
  }
628
746
  function publicSnapshot(owner) {
747
+ const activeBinding = owner.active?.lease.valid === true && owner.active.scope?.isCurrent() === true ? owner.active.binding : null;
629
748
  return Object.freeze({
630
749
  ready: owner.ready,
631
750
  environment: owner.registry.environment,
632
751
  profiles: accountProfilesByRecency(owner.registry),
633
752
  selectedProfileId: owner.registry.selectedProfileId,
634
- activeProfileId: owner.active?.profile.profileId || null,
753
+ activeBinding,
754
+ activeProfileId: activeBinding ? owner.active.profile.profileId : null,
755
+ activeScope: activeBinding?.scope || null,
756
+ activeScopeKey: activeBinding?.scope.key || null,
635
757
  status: owner.status,
636
758
  generation: owner.generation,
637
759
  error: owner.error
@@ -693,12 +815,23 @@ function ensureRequested(owner, generation, profileId) {
693
815
  throw staleTransitionError();
694
816
  }
695
817
  function transitionContext(owner, lease, reason, details = {}) {
818
+ const profile = lease.profileId ? owner.registry.profiles.find((item) => item.profileId === lease.profileId) || null : null;
819
+ const isCurrent = () => !owner.closing && !owner.closed && lease.valid;
696
820
  return Object.freeze({
821
+ environment: owner.registry.environment,
697
822
  generation: lease.generation,
698
823
  profileId: lease.profileId,
824
+ uid: profile?.uid || null,
699
825
  reason,
700
826
  ...details,
701
- isCurrent: () => !owner.closing && !owner.closed && lease.valid
827
+ scope: profile ? createAccountScope({
828
+ environment: owner.registry.environment,
829
+ generation: lease.generation,
830
+ profileId: lease.profileId,
831
+ uid: profile.uid,
832
+ isCurrent
833
+ }) : null,
834
+ isCurrent
702
835
  });
703
836
  }
704
837
  function report(owner, operation, error, profile = null) {
@@ -721,7 +854,13 @@ async function cleanupBinding(owner, binding, context) {
721
854
  binding.lease.valid = false;
722
855
  await attempt("lock", () => binding.runtime.lock());
723
856
  }
724
- await attempt("clearNotification", () => owner.ports.clearNotification(profile, context));
857
+ if (binding?.scope?.key && binding.scope.accountOwnerKey) {
858
+ await attempt("clearNotification", () => owner.ports.clearNotification(Object.freeze({
859
+ owner: binding.scope,
860
+ profile,
861
+ context
862
+ })));
863
+ }
725
864
  if (binding) {
726
865
  try {
727
866
  await owner.ports.dropPush(profile, binding.runtime, context);
@@ -821,7 +960,13 @@ async function openTarget(owner, profile, generation, reason, options = {}) {
821
960
  return discardCandidate(owner, profile, runtime, lease, "stale", null);
822
961
  }
823
962
  owner.openingLease = null;
824
- owner.active = { profile, runtime, lease };
963
+ owner.active = {
964
+ profile,
965
+ runtime,
966
+ lease,
967
+ scope: context.scope,
968
+ binding: Object.freeze({ runtime, scope: context.scope })
969
+ };
825
970
  publish(owner, "idle", null);
826
971
  return runtime;
827
972
  }
@@ -981,7 +1126,9 @@ async function applyAuthenticatedProfile(owner, profile, generation, reason, opt
981
1126
  }
982
1127
  async function resumeAuthenticatedProfile(owner, generation, reason, options = {}) {
983
1128
  publish(owner, reason, null);
984
- const profile = await resolveAuthenticatedProfile(owner, generation, reason);
1129
+ const profile = await resolveAuthenticatedProfile(owner, generation, reason, {
1130
+ rejectedProfileId: options.rejectedProfileId
1131
+ });
985
1132
  return applyAuthenticatedProfile(owner, profile, generation, reason, options);
986
1133
  }
987
1134
  function transitionFailure(owner, error, generation, profileId) {
@@ -1009,12 +1156,15 @@ async function initialize(owner) {
1009
1156
  throw error;
1010
1157
  }
1011
1158
  }
1012
- function requestAuthenticatedProfileResume(owner) {
1159
+ function requestAuthenticatedProfileResume(owner, options = {}) {
1013
1160
  ensureReady(owner);
1161
+ const rejectedProfileId = options.rejectedProfileId == null ? null : readAccountProfileId(options.rejectedProfileId);
1014
1162
  const generation = requestSelection(owner, null, false);
1015
1163
  return enqueue(owner, async () => {
1016
1164
  try {
1017
- return await resumeAuthenticatedProfile(owner, generation, "restoring");
1165
+ return await resumeAuthenticatedProfile(owner, generation, "restoring", {
1166
+ rejectedProfileId
1167
+ });
1018
1168
  } catch (error) {
1019
1169
  if (!isStaleAccountProfileTransition(error))
1020
1170
  publish(owner, "error", error);
@@ -1353,11 +1503,11 @@ function createAccountProfiles(options = {}) {
1353
1503
  const generation = requestSelection(owner, profileId, false);
1354
1504
  return enqueue(owner, () => switchExisting(owner, profileId, generation));
1355
1505
  },
1356
- resumeAuthenticated: () => requestAuthenticatedProfileResume(owner),
1506
+ resumeAuthenticated: (options2) => requestAuthenticatedProfileResume(owner, options2),
1357
1507
  refresh: () => requestProfileRefresh(owner),
1358
1508
  signOut: (profileId) => requestProfileSignOut(owner, profileId),
1359
1509
  remove: (profileId) => requestProfileRemoval(owner, profileId),
1360
- getActiveRuntime: () => owner.active?.runtime || null,
1510
+ getActiveBinding: () => owner.snapshot.activeBinding,
1361
1511
  close: () => closeProfiles(owner)
1362
1512
  });
1363
1513
  }
package/dist/auth.js CHANGED
@@ -82,8 +82,8 @@ function normalizePasskeyLoginError(error, options = {}) {
82
82
  return error;
83
83
  }
84
84
  function normalizePasskeyRegisterError(error, options = {}) {
85
- if (error?.name === "InvalidStateError" || error?.code === "functions/already-exists") {
86
- return passkeyError(PASSKEY_PROVIDER_ALREADY_LINKED, "this provider already has a passkey for this account. choose another provider, device, or security key", error);
85
+ if (error?.name === "CredentialAlreadyExistsException" || error?.name === "InvalidStateError" || error?.code === "functions/already-exists") {
86
+ return passkeyError(PASSKEY_PROVIDER_ALREADY_LINKED, "you already have a passkey for this account", error);
87
87
  }
88
88
  if (error?.code === "functions/failed-precondition") {
89
89
  return passkeyError(PASSKEY_RP_MISMATCH, "This passkey belongs to a different Glyphteck passkey setup.", error);
@@ -95,7 +95,7 @@ function normalizePasskeyRegisterError(error, options = {}) {
95
95
  }
96
96
 
97
97
  // ../../core/agreement.js
98
- var TERMS_VERSION = "2026-08-22.4";
98
+ var TERMS_VERSION = "2026-09-01.1";
99
99
  var CURRENT_AGREEMENT = Object.freeze({
100
100
  termsVersion: TERMS_VERSION
101
101
  });