@swype-org/react-sdk 0.1.87 → 0.1.88

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.cjs CHANGED
@@ -728,10 +728,10 @@ function isSafari() {
728
728
  var POPUP_RESULT_TIMEOUT_MS = 12e4;
729
729
  var POPUP_CLOSED_POLL_MS = 500;
730
730
  var POPUP_CLOSED_GRACE_MS = 1e3;
731
- function createPasskeyViaPopup(options, existingCredentialIds = []) {
731
+ function createPasskeyViaPopup(options) {
732
732
  return new Promise((resolve, reject) => {
733
- const channelId = `swype-pk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
734
- const payload = { ...options, channelId };
733
+ const verificationToken = crypto.randomUUID();
734
+ const payload = { ...options, verificationToken };
735
735
  const encoded = btoa(JSON.stringify(payload));
736
736
  const popupUrl = `${window.location.origin}/passkey-register#${encoded}`;
737
737
  const popup = window.open(popupUrl, "swype-passkey");
@@ -740,22 +740,21 @@ function createPasskeyViaPopup(options, existingCredentialIds = []) {
740
740
  return;
741
741
  }
742
742
  let settled = false;
743
- const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelId) : null;
744
743
  const timer = setTimeout(() => {
745
744
  cleanup();
746
745
  reject(new Error("Passkey creation timed out. Please try again."));
747
746
  }, POPUP_RESULT_TIMEOUT_MS);
748
- let closedGraceTimer = null;
749
747
  const closedPoll = setInterval(() => {
750
748
  if (popup.closed) {
751
749
  clearInterval(closedPoll);
752
- closedGraceTimer = setTimeout(() => {
750
+ setTimeout(() => {
753
751
  if (!settled) {
752
+ settled = true;
754
753
  cleanup();
755
- checkServerForNewPasskey(
754
+ checkServerForPasskeyByToken(
756
755
  options.authToken,
757
756
  options.apiBaseUrl,
758
- existingCredentialIds
757
+ verificationToken
759
758
  ).then((result) => {
760
759
  if (result) {
761
760
  resolve(result);
@@ -769,45 +768,18 @@ function createPasskeyViaPopup(options, existingCredentialIds = []) {
769
768
  }, POPUP_CLOSED_GRACE_MS);
770
769
  }
771
770
  }, POPUP_CLOSED_POLL_MS);
772
- function handleResult(data) {
773
- if (settled) return;
774
- if (!data || typeof data !== "object") return;
775
- if (data.type !== "swype:passkey-popup-result") return;
776
- settled = true;
777
- cleanup();
778
- if (data.error) {
779
- reject(new Error(data.error));
780
- } else if (data.result) {
781
- resolve(data.result);
782
- } else {
783
- reject(new Error("Invalid passkey popup response."));
784
- }
785
- }
786
- if (channel) {
787
- channel.onmessage = (event) => handleResult(event.data);
788
- }
789
- const postMessageHandler = (event) => {
790
- if (event.source !== popup) return;
791
- handleResult(event.data);
792
- };
793
- window.addEventListener("message", postMessageHandler);
794
771
  function cleanup() {
795
772
  clearTimeout(timer);
796
773
  clearInterval(closedPoll);
797
- if (closedGraceTimer) clearTimeout(closedGraceTimer);
798
- window.removeEventListener("message", postMessageHandler);
799
- channel?.close();
800
774
  }
801
775
  });
802
776
  }
803
777
  var VERIFY_POPUP_TIMEOUT_MS = 6e4;
804
778
  function findDevicePasskeyViaPopup(options) {
805
779
  return new Promise((resolve, reject) => {
806
- const channelId = `swype-pv-${Date.now()}-${Math.random().toString(36).slice(2)}`;
807
780
  const verificationToken = crypto.randomUUID();
808
781
  const payload = {
809
782
  ...options,
810
- channelId,
811
783
  verificationToken
812
784
  };
813
785
  const encoded = btoa(JSON.stringify(payload));
@@ -818,7 +790,6 @@ function findDevicePasskeyViaPopup(options) {
818
790
  return;
819
791
  }
820
792
  let settled = false;
821
- const channel = typeof BroadcastChannel !== "undefined" ? new BroadcastChannel(channelId) : null;
822
793
  const timer = setTimeout(() => {
823
794
  cleanup();
824
795
  resolve(null);
@@ -828,13 +799,14 @@ function findDevicePasskeyViaPopup(options) {
828
799
  clearInterval(closedPoll);
829
800
  setTimeout(() => {
830
801
  if (!settled) {
802
+ settled = true;
831
803
  cleanup();
832
- checkServerForVerifiedPasskey(
804
+ checkServerForPasskeyByToken(
833
805
  options.authToken,
834
806
  options.apiBaseUrl,
835
807
  verificationToken
836
- ).then((credentialId) => {
837
- resolve(credentialId);
808
+ ).then((result) => {
809
+ resolve(result?.credentialId ?? null);
838
810
  }).catch(() => {
839
811
  resolve(null);
840
812
  });
@@ -842,38 +814,13 @@ function findDevicePasskeyViaPopup(options) {
842
814
  }, POPUP_CLOSED_GRACE_MS);
843
815
  }
844
816
  }, POPUP_CLOSED_POLL_MS);
845
- function handleResult(data) {
846
- if (settled) return;
847
- if (!data || typeof data !== "object") return;
848
- if (data.type !== "swype:passkey-verify-result") return;
849
- settled = true;
850
- cleanup();
851
- if (data.error) {
852
- resolve(null);
853
- } else if (data.result && typeof data.result === "object") {
854
- const result = data.result;
855
- resolve(result.credentialId ?? null);
856
- } else {
857
- resolve(null);
858
- }
859
- }
860
- if (channel) {
861
- channel.onmessage = (event) => handleResult(event.data);
862
- }
863
- const postMessageHandler = (event) => {
864
- if (event.source !== popup) return;
865
- handleResult(event.data);
866
- };
867
- window.addEventListener("message", postMessageHandler);
868
817
  function cleanup() {
869
818
  clearTimeout(timer);
870
819
  clearInterval(closedPoll);
871
- window.removeEventListener("message", postMessageHandler);
872
- channel?.close();
873
820
  }
874
821
  });
875
822
  }
876
- async function checkServerForVerifiedPasskey(authToken, apiBaseUrl, verificationToken) {
823
+ async function checkServerForPasskeyByToken(authToken, apiBaseUrl, verificationToken) {
877
824
  if (!authToken || !apiBaseUrl) return null;
878
825
  const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
879
826
  headers: { Authorization: `Bearer ${authToken}` }
@@ -882,19 +829,7 @@ async function checkServerForVerifiedPasskey(authToken, apiBaseUrl, verification
882
829
  const body = await res.json();
883
830
  const passkeys = body.config.passkeys ?? [];
884
831
  const matched = passkeys.find((p) => p.lastVerificationToken === verificationToken);
885
- return matched?.credentialId ?? null;
886
- }
887
- async function checkServerForNewPasskey(authToken, apiBaseUrl, existingCredentialIds) {
888
- if (!authToken || !apiBaseUrl) return null;
889
- const res = await fetch(`${apiBaseUrl}/v1/users/config`, {
890
- headers: { Authorization: `Bearer ${authToken}` }
891
- });
892
- if (!res.ok) return null;
893
- const body = await res.json();
894
- const passkeys = body.config.passkeys ?? [];
895
- const existingSet = new Set(existingCredentialIds);
896
- const newPasskey = passkeys.find((p) => !existingSet.has(p.credentialId));
897
- return newPasskey ?? null;
832
+ return matched ? { credentialId: matched.credentialId, publicKey: matched.publicKey } : null;
898
833
  }
899
834
 
900
835
  // src/hooks.ts
@@ -5599,18 +5534,28 @@ function SwypePaymentInner({
5599
5534
  authToken: token ?? void 0,
5600
5535
  apiBaseUrl
5601
5536
  });
5602
- const { credentialId, publicKey } = await createPasskeyViaPopup(
5603
- popupOptions,
5604
- knownCredentialIds
5605
- );
5606
- await completePasskeyRegistration(credentialId, publicKey);
5537
+ const { credentialId } = await createPasskeyViaPopup(popupOptions);
5538
+ setActiveCredentialId(credentialId);
5539
+ localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, credentialId);
5540
+ setPasskeyPopupNeeded(false);
5541
+ const resolved = resolvePostAuthStep({
5542
+ hasPasskey: true,
5543
+ accounts,
5544
+ persistedMobileFlow: loadMobileFlowState(),
5545
+ mobileSetupInProgress: mobileSetupFlowRef.current,
5546
+ connectingNewAccount
5547
+ });
5548
+ if (resolved.clearPersistedFlow) {
5549
+ clearMobileFlowState();
5550
+ }
5551
+ setStep(resolved.step);
5607
5552
  } catch (err) {
5608
5553
  captureException(err);
5609
5554
  setError(err instanceof Error ? err.message : "Failed to register passkey");
5610
5555
  } finally {
5611
5556
  setRegisteringPasskey(false);
5612
5557
  }
5613
- }, [user, completePasskeyRegistration, getAccessToken, apiBaseUrl, knownCredentialIds]);
5558
+ }, [user, getAccessToken, apiBaseUrl, accounts, connectingNewAccount]);
5614
5559
  const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
5615
5560
  setVerifyingPasskeyPopup(true);
5616
5561
  setError(null);