set public key state

This commit is contained in:
Max Peintner
2023-06-30 15:32:41 +02:00
parent 9ba466387b
commit 02444814ef
5 changed files with 128 additions and 98 deletions

View File

@@ -60,7 +60,7 @@ export async function PUT(request: NextRequest) {
domain,
challenges
).then((session) => {
console.log(session.challenges);
console.log(session);
return NextResponse.json({
sessionId: session.id,
factors: session.factors,

View File

@@ -30,7 +30,7 @@
"clsx": "1.2.1",
"date-fns": "2.29.3",
"moment": "^2.29.4",
"next": "13.4.2",
"next": "13.4.7",
"next-themes": "^0.2.1",
"nice-grpc": "2.0.1",
"react": "18.2.0",

View File

@@ -1,6 +1,6 @@
"use client";
import { useEffect, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { ChallengeKind, Challenges_Passkey } from "@zitadel/server";
import { coerceToArrayBuffer, coerceToBase64Url } from "#/utils/base64";
@@ -15,12 +15,31 @@ type Props = {
export default function LoginPasskey({ loginName, challenge }: Props) {
const [error, setError] = useState<string>("");
const [publicKey, setPublicKey] = useState();
const [loading, setLoading] = useState<boolean>(false);
const router = useRouter();
const initialized = useRef(false);
useEffect(() => {
updateSessionForChallenge();
if (!initialized.current) {
initialized.current = true;
updateSessionForChallenge()
.then((response) => {
const pK =
response.challenges.passkey.publicKeyCredentialRequestOptions
.publicKey;
if (pK) {
setPublicKey(pK);
} else {
setError("Could not request passkey challenge");
}
})
.catch((error) => {
setError(error);
});
}
}, []);
async function updateSessionForChallenge() {
@@ -38,7 +57,8 @@ export default function LoginPasskey({ loginName, challenge }: Props) {
setLoading(false);
if (!res.ok) {
throw new Error("Failed to load authentication methods");
const error = await res.json();
throw error.details.details;
}
return res.json();
}
@@ -74,52 +94,52 @@ export default function LoginPasskey({ loginName, challenge }: Props) {
}
async function submitLoginAndContinue(): Promise<boolean | void> {
// navigator.credentials
// .get({
// publicKey: challenge.publicKeyCredentialRequestOptions,
// })
// .then((assertedCredential: any) => {
// if (assertedCredential) {
// let authData = new Uint8Array(
// assertedCredential.response.authenticatorData
// );
// let clientDataJSON = new Uint8Array(
// assertedCredential.response.clientDataJSON
// );
// let rawId = new Uint8Array(assertedCredential.rawId);
// let sig = new Uint8Array(assertedCredential.response.signature);
// let userHandle = new Uint8Array(
// assertedCredential.response.userHandle
// );
// let data = JSON.stringify({
// id: assertedCredential.id,
// rawId: coerceToBase64Url(rawId, "rawId"),
// type: assertedCredential.type,
// response: {
// authenticatorData: coerceToBase64Url(authData, "authData"),
// clientDataJSON: coerceToBase64Url(
// clientDataJSON,
// "clientDataJSON"
// ),
// signature: coerceToBase64Url(sig, "sig"),
// userHandle: coerceToBase64Url(userHandle, "userHandle"),
// },
// });
// return submitLogin(passkeyId, "", data, sessionId);
// } else {
// setLoading(false);
// setError("An error on retrieving passkey");
// return null;
// }
// })
// .catch((error) => {
// console.error(error);
// setLoading(false);
// // setError(error);
// return null;
// });
// }
// return router.push(`/accounts`);
console.log("login", publicKey);
navigator.credentials
.get({
publicKey,
})
.then((assertedCredential: any) => {
if (assertedCredential) {
let authData = new Uint8Array(
assertedCredential.response.authenticatorData
);
let clientDataJSON = new Uint8Array(
assertedCredential.response.clientDataJSON
);
let rawId = new Uint8Array(assertedCredential.rawId);
let sig = new Uint8Array(assertedCredential.response.signature);
let userHandle = new Uint8Array(
assertedCredential.response.userHandle
);
let data = JSON.stringify({
id: assertedCredential.id,
rawId: coerceToBase64Url(rawId, "rawId"),
type: assertedCredential.type,
response: {
authenticatorData: coerceToBase64Url(authData, "authData"),
clientDataJSON: coerceToBase64Url(
clientDataJSON,
"clientDataJSON"
),
signature: coerceToBase64Url(sig, "sig"),
userHandle: coerceToBase64Url(userHandle, "userHandle"),
},
});
console.log(data);
// return submitLogin(passkeyId, "", data, sessionId);
} else {
setLoading(false);
setError("An error on retrieving passkey");
return null;
}
})
.catch((error) => {
console.error(error);
setLoading(false);
// setError(error);
return null;
});
}
return (
@@ -143,7 +163,7 @@ export default function LoginPasskey({ loginName, challenge }: Props) {
type="submit"
className="self-end"
variant={ButtonVariants.Primary}
disabled={loading}
disabled={loading || !publicKey}
onClick={() => submitLoginAndContinue()}
>
{loading && <Spinner className="h-5 w-5 mr-2" />}

View File

@@ -66,12 +66,12 @@ export async function setSessionAndUpdateCookie(
domain,
password,
challenges
).then((session) => {
if (session) {
).then((updatedSession) => {
if (updatedSession) {
const sessionCookie: SessionCookie = {
id: sessionId,
token: session.sessionToken,
changeDate: session.details?.changeDate?.toString() ?? "",
token: updatedSession.sessionToken,
changeDate: updatedSession.details?.changeDate?.toString() ?? "",
loginName: loginName,
};
@@ -81,13 +81,13 @@ export async function setSessionAndUpdateCookie(
const { session } = response;
const newCookie: SessionCookie = {
id: sessionCookie.id,
token: sessionCookie.token,
token: updatedSession.sessionToken,
changeDate: session.changeDate?.toString() ?? "",
loginName: session.factors?.user?.loginName ?? "",
};
return updateSessionCookie(sessionCookie.id, newCookie).then(() => {
return session;
return { challenges: updatedSession.challenges, ...session };
});
} else {
throw "could not get session or session does not have loginName";