From 0932876fc3dea8773d8758d5119b6423bdf039f6 Mon Sep 17 00:00:00 2001 From: Mohammad Cheikh Date: Thu, 13 Feb 2025 12:14:54 -0500 Subject: [PATCH 1/2] patch fix for ewk session length and errors from useLocalStorage --- packages/sdk-react/package.json | 4 +-- .../sdk-react/src/components/auth/Auth.tsx | 31 ++++++++++++++++--- .../src/components/auth/OtpVerification.tsx | 10 ++++-- packages/sdk-react/src/hooks/use-session.ts | 4 ++- packages/sdk-react/src/hooks/use-turnkey.ts | 2 ++ pnpm-lock.yaml | 27 ++++++++-------- 6 files changed, 54 insertions(+), 24 deletions(-) diff --git a/packages/sdk-react/package.json b/packages/sdk-react/package.json index a91efbccb..9439d15a0 100644 --- a/packages/sdk-react/package.json +++ b/packages/sdk-react/package.json @@ -59,11 +59,11 @@ "@turnkey/sdk-browser": "workspace:*", "@turnkey/sdk-server": "workspace:*", "@turnkey/wallet-stamper": "workspace:*", - "@uidotdev/usehooks": "^2.4.1", "libphonenumber-js": "^1.11.14", "next": "^15.0.2", "react-apple-login": "^1.1.6", - "react-international-phone": "^4.3.0" + "react-international-phone": "^4.3.0", + "usehooks-ts": "^3.1.1" }, "peerDependencies": { "@types/react": "^18.2.75", diff --git a/packages/sdk-react/src/components/auth/Auth.tsx b/packages/sdk-react/src/components/auth/Auth.tsx index 21e6b34a4..a6a00807e 100644 --- a/packages/sdk-react/src/components/auth/Auth.tsx +++ b/packages/sdk-react/src/components/auth/Auth.tsx @@ -172,10 +172,16 @@ const Auth: React.FC = ({ return suborgId; }; - const handleAuthSuccess = async (credentialBundle: any) => { + const handleAuthSuccess = async ( + credentialBundle: any, + expirationSeconds?: string, + ) => { if (credentialBundle) { await authIframeClient!.injectCredentialBundle(credentialBundle); - await authIframeClient!.loginWithAuthBundle(credentialBundle); + await authIframeClient!.loginWithAuthBundle( + credentialBundle, + expirationSeconds, + ); await onAuthSuccess(); } }; @@ -223,12 +229,18 @@ const Auth: React.FC = ({ const sessionResponse = await passkeyClient?.createReadWriteSession({ targetPublicKey: authIframeClient?.iframePublicKey!, + ...(authConfig.sessionLengthSeconds !== undefined && { + expirationSeconds: authConfig.sessionLengthSeconds.toString(), + }), organizationId: turnkey?.config.defaultOrganizationId ?? process.env.NEXT_PUBLIC_ORGANIZATION_ID!, }); if (sessionResponse?.credentialBundle) { - await handleAuthSuccess(sessionResponse.credentialBundle); + await handleAuthSuccess( + sessionResponse.credentialBundle, + authConfig.sessionLengthSeconds?.toString(), + ); } else { setPasskeySignupError(authErrors.passkey.loginFailed); } @@ -241,13 +253,19 @@ const Auth: React.FC = ({ try { const sessionResponse = await passkeyClient?.createReadWriteSession({ targetPublicKey: authIframeClient?.iframePublicKey!, + ...(authConfig.sessionLengthSeconds !== undefined && { + expirationSeconds: authConfig.sessionLengthSeconds.toString(), + }), organizationId: turnkey?.config.defaultOrganizationId ?? process.env.NEXT_PUBLIC_ORGANIZATION_ID!, }); if (sessionResponse?.credentialBundle) { - await handleAuthSuccess(sessionResponse.credentialBundle); + await handleAuthSuccess( + sessionResponse.credentialBundle, + authConfig.sessionLengthSeconds?.toString(), + ); } else { authErrors.passkey.loginFailed; } @@ -294,7 +312,10 @@ const Auth: React.FC = ({ sessionLengthSeconds: authConfig.sessionLengthSeconds, }); if (oauthResponse && oauthResponse.token) { - await handleAuthSuccess(oauthResponse!.token); + await handleAuthSuccess( + oauthResponse!.token, + authConfig.sessionLengthSeconds?.toString(), + ); } else { onError(authErrors.oauth.loginFailed); } diff --git a/packages/sdk-react/src/components/auth/OtpVerification.tsx b/packages/sdk-react/src/components/auth/OtpVerification.tsx index 31b2d3d9a..efe4bdc97 100644 --- a/packages/sdk-react/src/components/auth/OtpVerification.tsx +++ b/packages/sdk-react/src/components/auth/OtpVerification.tsx @@ -18,7 +18,10 @@ interface OtpVerificationProps { otpId: string; authIframeClient: any; sessionLengthSeconds?: number | undefined; - onValidateSuccess: (credentialBundle: any) => Promise; + onValidateSuccess: ( + credentialBundle: any, + expirationSeconds?: string, + ) => Promise; onResendCode: ( type: FilterType.Email | FilterType.PhoneNumber, value: string, @@ -53,7 +56,10 @@ const OtpVerification: React.FC = ({ }); if (authResponse?.token) { - await onValidateSuccess(authResponse.token); + await onValidateSuccess( + authResponse.token, + sessionLengthSeconds?.toString(), + ); } else { setOtpError("Invalid code. Please try again."); } diff --git a/packages/sdk-react/src/hooks/use-session.ts b/packages/sdk-react/src/hooks/use-session.ts index 07ebdb1bc..45fb67ed4 100644 --- a/packages/sdk-react/src/hooks/use-session.ts +++ b/packages/sdk-react/src/hooks/use-session.ts @@ -1,5 +1,7 @@ +"use client"; + import { StorageKeys, User } from "@turnkey/sdk-browser"; -import { useLocalStorage } from "@uidotdev/usehooks"; +import { useLocalStorage } from "usehooks-ts"; interface UserSession { user?: Omit | undefined; diff --git a/packages/sdk-react/src/hooks/use-turnkey.ts b/packages/sdk-react/src/hooks/use-turnkey.ts index f28d4d450..5c9975f1e 100644 --- a/packages/sdk-react/src/hooks/use-turnkey.ts +++ b/packages/sdk-react/src/hooks/use-turnkey.ts @@ -1,3 +1,5 @@ +"use client"; + import { useContext } from "react"; import { TurnkeyContext } from "../contexts/TurnkeyContext"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94ceeba80..37f7bd2e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1823,9 +1823,6 @@ importers: '@types/react': specifier: ^18.2.75 version: 18.2.75 - '@uidotdev/usehooks': - specifier: ^2.4.1 - version: 2.4.1(react-dom@18.3.1)(react@18.2.0) libphonenumber-js: specifier: ^1.11.14 version: 1.11.14 @@ -1838,6 +1835,9 @@ importers: react-international-phone: specifier: ^4.3.0 version: 4.3.0(react@18.2.0) + usehooks-ts: + specifier: ^3.1.1 + version: 3.1.1(react@18.2.0) devDependencies: postcss-import: specifier: ^16.1.0 @@ -13447,17 +13447,6 @@ packages: '@typescript-eslint/types': 7.2.0 eslint-visitor-keys: 3.4.3 - /@uidotdev/usehooks@2.4.1(react-dom@18.3.1)(react@18.2.0): - resolution: {integrity: sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==} - engines: {node: '>=16'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - dependencies: - react: 18.2.0 - react-dom: 18.3.1(react@18.2.0) - dev: false - /@ungap/structured-clone@1.2.1: resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} dev: false @@ -24936,6 +24925,16 @@ packages: react: 18.2.0 dev: false + /usehooks-ts@3.1.1(react@18.2.0): + resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} + engines: {node: '>=16.15.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + dependencies: + lodash.debounce: 4.0.8 + react: 18.2.0 + dev: false + /utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} From faa757cf2b6afe1aa76566466c13cd6c209a3dcf Mon Sep 17 00:00:00 2001 From: Mohammad Cheikh Date: Thu, 13 Feb 2025 12:15:33 -0500 Subject: [PATCH 2/2] add changeset --- .changeset/khaki-glasses-teach.md | 5 +++++ packages/sdk-react/README.md | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changeset/khaki-glasses-teach.md diff --git a/.changeset/khaki-glasses-teach.md b/.changeset/khaki-glasses-teach.md new file mode 100644 index 000000000..380ca3089 --- /dev/null +++ b/.changeset/khaki-glasses-teach.md @@ -0,0 +1,5 @@ +--- +"@turnkey/sdk-react": patch +--- + +Patch EWK custom session lengths - previously not working as intended (defaulted to 15 minute sessions only) and fix the following useLocalStorage issue when compiling: [Error: useLocalStorage is a client-only hook] diff --git a/packages/sdk-react/README.md b/packages/sdk-react/README.md index cc1daf37e..526d46e89 100644 --- a/packages/sdk-react/README.md +++ b/packages/sdk-react/README.md @@ -120,6 +120,7 @@ function AuthPage() { googleEnabled: true, appleEnabled: false, facebookEnabled: false, + sessionLengthSeconds: 3600, //1 hour r/w session }; const configOrder = ["socials", "email", "phone", "passkey"];