tkhq / passkeyapp

Minimal React Native app featuring native passkeys and integration with Turnkey
4 stars 4 forks source link

ERROR Error during passkey creation {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@7337b1"}. #6

Open vikasvk3510 opened 1 month ago

vikasvk3510 commented 1 month ago

ERROR Error during passkey creation {"error": "Native error", "message": "androidx.credentials.exceptions.domerrors.SecurityError@7337b1"}. WHY THIS HAPPENS

r-n-o commented 1 month ago

@vikasvk3510 unsure why this is happening at first glance, but "SecurityError" hints at some kind of policy being violated. Maybe because the RPID isn't compatible with the domain? You need to host a /.well-known/assetlinks.json at the root of your domain for passkey creation to work correctly.

vikasvk3510 commented 4 weeks ago

I am using my domain but it's not working. Is there any other implementation for android because it's showing the same error .

On Fri, 25 Oct 2024 at 21:01, Arnaud @.***> wrote:

@vikasvk3510 https://github.com/vikasvk3510 unsure why this is happening at first glance, but "SecurityError" hints at some kind of policy being violated. Maybe because the RPID isn't compatible with the domain? You need to host a /.well-known/assetlinks.json at the root of your domain for passkey creation to work correctly.

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2438131938, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WWXYZLIKIXVGOBRLWTZ5JP6NAVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMZYGEZTCOJTHA . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 4 weeks ago

If you're comfortable doing so, can you share your domain and a link to your repo? Unfortunately my experience with native passkey implementation is that it's quite finicky and hard to debug. Just to name a few things I ran into: the app being signed with the wrong debug cert, app run in a context which doesn't allow passkeys, app domain and RPID mismatch because of typos or subdomains, wrong Content-Type headers on files hosted at /.well-known/..., hosted files being cached by Apple/Google's infrastructure.

Enabling device-side debug logs might help. As-is it's difficult for me to really dig in without more information.

vikasvk3510 commented 3 weeks ago

Please check this code i am using while create pass key

const authenticatorParams = await createPasskey( { authenticatorName: "End-User Passkey", rp: { id: 'abstraxn.com', // Ensure this is your ngrok or valid HTTPS domain name: "abstraxn", }, user: { id: userId, name: Key @ ${humanReadableDateTime}, displayName: Key @ ${humanReadableDateTime}, }, authenticatorSelection: { residentKey: "preferred", // or "preferred" userVerification: "discouraged", // or "discouraged" }, }

);

and here the backend domain setup you can check in the URL https://yurl.chayev.com/android-results?url=abstraxn.com&prefix=&bundle=

On Tue, 29 Oct 2024 at 21:13, Arnaud @.***> wrote:

If you're comfortable doing so, can you share your domain and a link to your repo? Unfortunately my experience with native passkey implementation is that it's quite finicky and hard to debug. Just to name a few things I ran into: the app being signed with the wrong debug cert, app run in a context which doesn't allow passkeys, app domain and RPID mismatch because of typos or subdomains, wrong Content-Type headers on files hosted at /.well-known/..., hosted files being cached by Apple/Google's infrastructure.

Enabling device-side debug logs might help. As-is it's difficult for me to really dig in without more information.

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2444658839, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WQGE3BHH7GCYMP5FBTZ56UKTAVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBUGY2TQOBTHE . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 3 weeks ago

@vikasvk3510 shot in the dark: could it be the same issue than what I've encountered in https://github.com/f-23/react-native-passkey/issues/29#issuecomment-1939523309? What is the value of userId in your code? Android requires that it's a valid base64-encoded string.

vikasvk3510 commented 3 weeks ago

userID = MTczMDY5MzMwMTU0OA==

On Wed, 30 Oct 2024 at 20:03, Arnaud @.***> wrote:

@vikasvk3510 https://github.com/vikasvk3510 shot in the dark: could it be the same issue than what I've encountered in f-23/react-native-passkey#29 (comment) https://github.com/f-23/react-native-passkey/issues/29#issuecomment-1939523309? What is the value of userId in your code? Android requires that it's a valid base64-encoded string.

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2447357259, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WUQV7RYOBPHI4WWBY3Z6DU4DAVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBXGM2TOMRVHE . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 3 weeks ago

Ok cool. So that's not it then. Looks like perfectly valid base64 to me!

vikasvk3510 commented 3 weeks ago

still i am getting same error please provide solution check this code import React, { useEffect, useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, SafeAreaView, StatusBar } from 'react-native'; import { Colors } from '../../../../AppTheme/colors'; import { staticValues } from '../../../../Constants/staticData'; import { showErrorMessageBar } from '../../../../Helpers/snackBar'; import { PasskeyStamper, createPasskey, isSupported, } from @./react-native-passkey-stamper"; import { ApiKeyStamper } from @./api-key-stamper"; import { TurnkeyClient } from @.***/http"; import { Buffer } from "buffer"; import { navigationRoutes } from '../../../../Constants/navigation'; import { styles } from './signUpStyle'; import { log } from 'console'; import { SagaActions } from '../../../../Redux/sagaActions'; import { useDispatch } from 'react-redux'; import { showMessage } from 'react-native-flash-message'; import { actuatedNormalize } from '../../../../Helpers/responsiveScreen'; import { Fonts } from '../../../../AppTheme/fonts';

interface SignInProps { navigation: any; }

const Signup: React.FC = ({ navigation }) => {

const dispatch = useDispatch() const RPID = "abstraxn.com"; const [username, setUsername] = useState(''); const [debounceTimeout, setDebounceTimeout] = useState(null); const [ShowMessage, setShowMessage] = useState(''); const [isVisible, setIsVisible] = useState(true);

useEffect(() => { if (ShowMessage) { setIsVisible(true); // Show message when set const timer = setTimeout(() => { setIsVisible(false); setShowMessage(''); // Clear the message after hiding it }, 3000);

return () => clearTimeout(timer); // Clear timeout if component unmounts } }, [ShowMessage]); ////////////////////CREATE PASS KEY///////////////////////////// async function onPasskeyCreate() { if (!isSupported()) { alert("Passkeys are not supported on this device"); return; }

try { const now = new Date(); const humanReadableDateTime = ${now.getFullYear()}-${now.getMonth() + 1}-${ now.getDate()} @ ${now.getHours()}h${now.getMinutes()}min; console.log("Creating passkey with datetime: ", humanReadableDateTime); // const userId = Buffer.from(String(Date.now())).toString("base64"); const userId = Buffer.from(String(Date.now())).toString("base64");

console.log('use ID===>', userId);

const authenticatorParams = await createPasskey( { authenticatorName: "End-User Passkey", rp: { id: 'abstraxn.com', // Ensure this is your ngrok or valid HTTPS domain name: "Abstraxn SW", }, // challenge: userId, user: { id: userId, name: sandeep, displayName: sandeep, }, authenticatorSelection: { residentKey: "preferred", // Allow both stored and non-stored keys userVerification: "preferred", }, attestation: 'direct' }

);

console.log("Passkey registration succeeded: ", authenticatorParams); const response = await createSubOrganization(authenticatorParams); console.log("Created sub-org", response); alert(Sub-org created! Your ID: ${response.activity.result. createSubOrganizationResultV4?.subOrganizationId}); } catch (e) { console.error("Error during passkey creation", e); alert(Error during passkey creation: ${e}); } } ////////////////////CREATE SUB ORGINISATION///////////////////// async function createSubOrganization( authenticatorParams: Awaited<ReturnType>, ) { const stamper = new ApiKeyStamper({ apiPublicKey: 'dummyPublicKey_1234567890', apiPrivateKey: "dummyPrivateKey_0987654321", }); const client = new TurnkeyClient( { baseUrl: "https://api.turnkey.com" }, stamper, );

const data = await client.createSubOrganization({ type: "ACTIVITY_TYPE_CREATE_SUB_ORGANIZATION_V4", timestampMs: String(Date.now()), organizationId: "dummyOrganizationId_001", parameters: { subOrganizationName: Sub-organization at ${String(Date.now())}, rootQuorumThreshold: 1, rootUsers: [ { userName: "Root User", apiKeys: [], authenticators: [authenticatorParams], // oauthProviders: [] }, ], }, }); return data; } ////////////////////HANDLE ACCOUNT CREATE////////////////////// const handleUsernameChange = (text: string) => { setUsername(text); if (debounceTimeout) clearTimeout(debounceTimeout); const newTimeout = setTimeout(() => { checkUser(text); }, 500); // Adjust delay as needed setDebounceTimeout(newTimeout); }; ///////////////////////////////////////////////////////////// const checkUser = (name: string) => { const trimmedUsername = name.trim(); if (trimmedUsername.length === 0) return; if (trimmedUsername.length < 4) { showErrorMessageBar('Username must be at least 4 characters long.'); return; } dispatch({ type: SagaActions.CHECK_USER_NAME, payload: {

username: username, CheckUserName: async (data: any) => { console.log('Checking username:', data.message); setShowMessage(data.message)

}, CheckUserNameError: async (err: any | null) => { console.error('Error:', err); }, }, }); };

return (

{staticValues.CREATE_YOUR} {staticValues.ABSTRAXN_ACCOUNT} {staticValues.DIAPLAYNAME} {isVisible && ShowMessage && ( {ShowMessage} )} {staticValues.BY_CONTIUING} navigation.navigate(navigationRoutes.CreatingYourAccount)} > {staticValues.CREATE_ACC_WITH_PASS_KEY} navigation. navigate(navigationRoutes.LoginScreen)}> {staticValues.OR_LOGIN} navigation.navigate(navigationRoutes. LoginScreen)}> {staticValues.SIGNIN_WITH_PASSKEY} {staticValues.ACCOUNT_SECURED} navigation.navigate(navigationRoutes. CreatingYourAccount)} style={styles.learnMoreButton}> {staticValues.LEARN_MORE}

); };

export default Signup;

On Mon, 4 Nov 2024 at 19:28, Arnaud @.***> wrote:

Ok cool. So that's not it then. Looks like perfectly valid base64 to me!

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2454787970, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WS7URIEK6VPWREPIK3Z65VP7AVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJUG44DOOJXGA . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 3 weeks ago

Two things jump out from a quick glance

The rest of your code looks good to me; I bet the issue, if not related to createPasskey params somehow, is going to be related to the setup you're testing with: are you testing locally with a signed APK? Deploying into a test device? I've run into many issues testing on Android emulators in particular so I'd recommend actually building the signed APK, and install it on a dev-enabled device to remove any weirdness.

vikasvk3510 commented 2 weeks ago

@Arnaud The issue of {"error": "Native error", "message": @.***"}. is fixed now. i have one more query, can i get

in my response in React Native App

because this pubkeyCoordinates response is showing in web , i want that same same response in React Native mobile app

On Tue, 5 Nov 2024 at 20:59, Arnaud @.***> wrote:

Two things jump out from a quick glance

  • authenticatorSelection for createPasskey doesn't require resident keys. Most likely this is fine, but it'd be interesting to try creating a passkey with the exact same configuration than what is here https://github.com/tkhq/passkeyapp/blob/e0540c2aa213fb4cf9bb723edb2f0504e636f380/Home.tsx#L81-L85 to eliminate this variable
  • attestation: "direct" is passed in; let's try without it? Again I don't see a problem with that in principle, but anything you can do to remove differences will help isolate the problem

The rest of your code looks good to me; I bet the issue, if not related to createPasskey params somehow, is going to be related to the setup you're testing with: are you testing locally with a signed APK? Deploying into a test device? I've run into many issues testing on Android emulators in particular so I'd recommend actually building the signed APK, and install it on a dev-enabled device to remove any weirdness.

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2457478167, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WR7TJHVWLOJVIM5LPTZ7DP55AVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINJXGQ3TQMJWG4 . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 2 weeks ago

@vikasvk3510 great news! Mind sharing what was the problem and how you got around it?

Re: public key coordinates: can you be more specific about where you see this "showing in web"? Are you referring to Turnkey API responses? Or a demo app? Also: which key do you want to display pubkey coordinates for?

vikasvk3510 commented 2 weeks ago

MOBILE OBJECT

createPasskey({ authenticatorName: "End-UserPasskey", rp: { id: "abstraxn.com", // Ensure this is your valid domain name: "com.abstraxn", }, user: { id: userId, name: User_${now.getTime()}, displayName: User_${now.getTime()}, }, authenticatorSelection: { residentKey: "preferred", // Allow both stored and non-stored keys userVerification: "preferred", }, publicKey: { pubKeyCredParams: [ { alg: -7, type: "public-key" }, // ES256 (Webauthn's default algorithm) { alg: -257, type: "public-key" }, // RS256 (for older Windows Hello and others) ] } });

-----------------------------------------------------------WEB OBJECT

{ publicKey: { pubKeyCredParams: [ { alg: -7, type: "public-key" }, // ES256 (Webauthn's default algorithm) { alg: -257, type: "public-key" }, // RS256 (for older Windows Hello and others) ], challenge: crypto.getRandomValues(new Uint8Array(32)), rp: { name: 'Abstraxn SmartAccount', }, user: { displayName: username, id: crypto.getRandomValues(new Uint8Array(32)), name: username, }, timeout: 60_000, authenticatorSelection: { userVerification: 'preferred', residentKey: 'preferred', }, attestation: 'direct' }

PubKeyCredParams is return x and y fingerprint coordinates in web example( pubkeyCoordinates Response

) i want that same response in mobile app

On Fri, 8 Nov 2024 at 21:23, Arnaud @.***> wrote:

@vikasvk3510 https://github.com/vikasvk3510 great news! Mind sharing what was the problem and how you got around it?

Re: public key coordinates: can you be more specific about where you see this "showing in web"? Are you referring to Turnkey API responses? Or a demo app? Also: which key do you want to display pubkey coordinates for?

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2465099267, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WUTUQJWYEVYSBQO2SLZ7TNBHAVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINRVGA4TSMRWG4 . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 2 weeks ago

Interesting, thanks for sharing! The only difference between this and what you had before seems to be the removal of "attestation: direct" from the config passed to createPasskey? Anything else besides that? (any changes in your HTTP server or device/test setup which wouldn't be captured by an app code change?)

vikasvk3510 commented 1 week ago

Arnaud. i am getting stuck on IOS while opening passkey in ios

Error creating passkey: {"error": "RequestFailed", "message": "The request failed. No Credentials were returned."}

On Mon, 11 Nov 2024 at 20:19, Arnaud @.***> wrote:

Interesting, thanks for sharing! The only difference between this and what you had before seems to be the removal of "attestation: direct" from the config passed to createPasskey? Anything else besides that? (any changes in your HTTP server or device/test setup which wouldn't be captured by an app code change?)

— Reply to this email directly, view it on GitHub https://github.com/tkhq/passkeyapp/issues/6#issuecomment-2468358081, or unsubscribe https://github.com/notifications/unsubscribe-auth/BAOH5WT6QKEUHY6QK2RPET32AC7X5AVCNFSM6AAAAABQSSG34KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINRYGM2TQMBYGE . You are receiving this because you were mentioned.Message ID: @.***>

r-n-o commented 1 week ago

It's going to be difficult for me to help without further details. By "opening" passkeys you mean during authentication? Or registration? It'd be helpful to know how you're testing exactly because it will affect what you can and can't do on iOS.

One thing that's iOS specific is the provisioning profile and app signing process: without that in place I don't think passkeys will work. Another thing to check is the app entitlements. Unfortunately these are "off the cuff" recommendations, I'm not sure they'll fix the issue you're seeing (they're just things that have bitten me before)