@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 +29 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -28
- package/dist/index.d.ts +12 -28
- package/dist/index.js +29 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
|
731
|
+
function createPasskeyViaPopup(options) {
|
|
732
732
|
return new Promise((resolve, reject) => {
|
|
733
|
-
const
|
|
734
|
-
const payload = { ...options,
|
|
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
|
-
|
|
750
|
+
setTimeout(() => {
|
|
753
751
|
if (!settled) {
|
|
752
|
+
settled = true;
|
|
754
753
|
cleanup();
|
|
755
|
-
|
|
754
|
+
checkServerForPasskeyByToken(
|
|
756
755
|
options.authToken,
|
|
757
756
|
options.apiBaseUrl,
|
|
758
|
-
|
|
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
|
-
|
|
804
|
+
checkServerForPasskeyByToken(
|
|
833
805
|
options.authToken,
|
|
834
806
|
options.apiBaseUrl,
|
|
835
807
|
verificationToken
|
|
836
|
-
).then((
|
|
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
|
|
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
|
|
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
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
);
|
|
5606
|
-
|
|
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,
|
|
5558
|
+
}, [user, getAccessToken, apiBaseUrl, accounts, connectingNewAccount]);
|
|
5614
5559
|
const handleVerifyPasskeyViaPopup = react.useCallback(async () => {
|
|
5615
5560
|
setVerifyingPasskeyPopup(true);
|
|
5616
5561
|
setError(null);
|