mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 10:04:25 +00:00
login submit passkey credential
This commit is contained in:
@@ -1,11 +1,10 @@
|
|||||||
import { server, deleteSession, getSession, setSession } from "#/lib/zitadel";
|
import { server, deleteSession } from "#/lib/zitadel";
|
||||||
import {
|
import {
|
||||||
SessionCookie,
|
SessionCookie,
|
||||||
getMostRecentSessionCookie,
|
getMostRecentSessionCookie,
|
||||||
getSessionCookieById,
|
getSessionCookieById,
|
||||||
getSessionCookieByLoginName,
|
getSessionCookieByLoginName,
|
||||||
removeSessionFromCookie,
|
removeSessionFromCookie,
|
||||||
updateSessionCookie,
|
|
||||||
} from "#/utils/cookies";
|
} from "#/utils/cookies";
|
||||||
import {
|
import {
|
||||||
createSessionAndUpdateCookie,
|
createSessionAndUpdateCookie,
|
||||||
@@ -38,7 +37,7 @@ export async function PUT(request: NextRequest) {
|
|||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
|
|
||||||
if (body) {
|
if (body) {
|
||||||
const { loginName, password, challenges } = body;
|
const { loginName, password, challenges, passkey } = body;
|
||||||
|
|
||||||
const recentPromise: Promise<SessionCookie> = loginName
|
const recentPromise: Promise<SessionCookie> = loginName
|
||||||
? getSessionCookieByLoginName(loginName).catch((error) => {
|
? getSessionCookieByLoginName(loginName).catch((error) => {
|
||||||
@@ -57,6 +56,7 @@ export async function PUT(request: NextRequest) {
|
|||||||
recent.token,
|
recent.token,
|
||||||
recent.loginName,
|
recent.loginName,
|
||||||
password,
|
password,
|
||||||
|
passkey,
|
||||||
domain,
|
domain,
|
||||||
challenges
|
challenges
|
||||||
).then((session) => {
|
).then((session) => {
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ export async function setSession(
|
|||||||
sessionToken: string,
|
sessionToken: string,
|
||||||
domain: string | undefined,
|
domain: string | undefined,
|
||||||
password: string | undefined,
|
password: string | undefined,
|
||||||
|
passkey: { credentialAssertionData: any } | undefined,
|
||||||
challenges: ChallengeKind[] | undefined
|
challenges: ChallengeKind[] | undefined
|
||||||
): Promise<SetSessionResponse | undefined> {
|
): Promise<SetSessionResponse | undefined> {
|
||||||
const sessionService = session.getSession(server);
|
const sessionService = session.getSession(server);
|
||||||
@@ -125,7 +126,7 @@ export async function setSession(
|
|||||||
? sessionService.setSession(
|
? sessionService.setSession(
|
||||||
{
|
{
|
||||||
...payload,
|
...payload,
|
||||||
checks: { password: { password } },
|
checks: { password: { password }, passkey },
|
||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -63,23 +63,16 @@ export default function LoginPasskey({ loginName, challenge }: Props) {
|
|||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitLogin(
|
async function submitLogin(data: any) {
|
||||||
passkeyId: string,
|
|
||||||
passkeyName: string,
|
|
||||||
publicKeyCredential: any,
|
|
||||||
sessionId: string
|
|
||||||
) {
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const res = await fetch("/api/passkeys/verify", {
|
const res = await fetch("/api/session", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
passkeyId,
|
loginName,
|
||||||
passkeyName,
|
passkey: data,
|
||||||
publicKeyCredential,
|
|
||||||
sessionId,
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,51 +88,65 @@ export default function LoginPasskey({ loginName, challenge }: Props) {
|
|||||||
|
|
||||||
async function submitLoginAndContinue(): Promise<boolean | void> {
|
async function submitLoginAndContinue(): Promise<boolean | void> {
|
||||||
console.log("login", publicKey);
|
console.log("login", publicKey);
|
||||||
navigator.credentials
|
if (publicKey) {
|
||||||
.get({
|
console.log(publicKey);
|
||||||
publicKey,
|
(publicKey as any).challenge = coerceToArrayBuffer(
|
||||||
})
|
(publicKey as any).challenge,
|
||||||
.then((assertedCredential: any) => {
|
"publicKey.challenge"
|
||||||
if (assertedCredential) {
|
);
|
||||||
let authData = new Uint8Array(
|
(publicKey as any).allowCredentials.map((listItem: any) => {
|
||||||
assertedCredential.response.authenticatorData
|
listItem.id = coerceToArrayBuffer(
|
||||||
);
|
listItem.id,
|
||||||
let clientDataJSON = new Uint8Array(
|
"publicKey.allowCredentials.id"
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
|
console.log(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(data);
|
||||||
|
} else {
|
||||||
|
setLoading(false);
|
||||||
|
setError("An error on retrieving passkey");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
setLoading(false);
|
||||||
|
// setError(error);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
addSessionToCookie,
|
addSessionToCookie,
|
||||||
updateSessionCookie,
|
updateSessionCookie,
|
||||||
} from "./cookies";
|
} from "./cookies";
|
||||||
import { ChallengeKind, Session } from "@zitadel/server";
|
import { ChallengeKind, Session, Challenges } from "@zitadel/server";
|
||||||
|
|
||||||
export async function createSessionAndUpdateCookie(
|
export async function createSessionAndUpdateCookie(
|
||||||
loginName: string,
|
loginName: string,
|
||||||
@@ -51,20 +51,24 @@ export async function createSessionAndUpdateCookie(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SessionWithChallenges = Session & { challenges: Challenges[] };
|
||||||
|
|
||||||
export async function setSessionAndUpdateCookie(
|
export async function setSessionAndUpdateCookie(
|
||||||
sessionId: string,
|
sessionId: string,
|
||||||
sessionToken: string,
|
sessionToken: string,
|
||||||
loginName: string,
|
loginName: string,
|
||||||
password: string | undefined,
|
password: string | undefined,
|
||||||
|
passkey: { credentialAssertionData: any } | undefined,
|
||||||
domain: string | undefined,
|
domain: string | undefined,
|
||||||
challenges: ChallengeKind[] | undefined
|
challenges: ChallengeKind[] | undefined
|
||||||
): Promise<Session> {
|
): Promise<SessionWithChallenges> {
|
||||||
return setSession(
|
return setSession(
|
||||||
server,
|
server,
|
||||||
sessionId,
|
sessionId,
|
||||||
sessionToken,
|
sessionToken,
|
||||||
domain,
|
domain,
|
||||||
password,
|
password,
|
||||||
|
passkey,
|
||||||
challenges
|
challenges
|
||||||
).then((updatedSession) => {
|
).then((updatedSession) => {
|
||||||
if (updatedSession) {
|
if (updatedSession) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export { LoginSettings } from "./proto/server/zitadel/settings/v2alpha/login_set
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
ChallengeKind,
|
ChallengeKind,
|
||||||
|
Challenges,
|
||||||
Challenges_Passkey,
|
Challenges_Passkey,
|
||||||
} from "./proto/server/zitadel/session/v2alpha/challenge";
|
} from "./proto/server/zitadel/session/v2alpha/challenge";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user