mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 10:25:58 +00:00
createpasskeyregistrationlink
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
import { getSession, server } from "#/lib/zitadel";
|
import { getSession, server } from "#/lib/zitadel";
|
||||||
import Alert from "#/ui/Alert";
|
import Alert, { AlertType } from "#/ui/Alert";
|
||||||
import RegisterPasskey from "#/ui/RegisterPasskey";
|
import RegisterPasskey from "#/ui/RegisterPasskey";
|
||||||
import UserAvatar from "#/ui/UserAvatar";
|
import UserAvatar from "#/ui/UserAvatar";
|
||||||
import { getMostRecentCookieWithLoginname } from "#/utils/cookies";
|
import { getMostRecentCookieWithLoginname } from "#/utils/cookies";
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
|
|
||||||
export default async function Page({
|
export default async function Page({
|
||||||
searchParams,
|
searchParams,
|
||||||
@@ -15,7 +14,6 @@ export default async function Page({
|
|||||||
|
|
||||||
async function loadSession(loginName?: string) {
|
async function loadSession(loginName?: string) {
|
||||||
const recent = await getMostRecentCookieWithLoginname(loginName);
|
const recent = await getMostRecentCookieWithLoginname(loginName);
|
||||||
|
|
||||||
return getSession(server, recent.id, recent.token).then((response) => {
|
return getSession(server, recent.id, recent.token).then((response) => {
|
||||||
if (response?.session) {
|
if (response?.session) {
|
||||||
return response.session;
|
return response.session;
|
||||||
@@ -27,7 +25,14 @@ export default async function Page({
|
|||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center space-y-4">
|
<div className="flex flex-col items-center space-y-4">
|
||||||
<h1>Register Passkey</h1>
|
<h1>Register Passkey</h1>
|
||||||
<p className="ztdl-p mb-6 block">Setup your device for passkeys.</p>
|
<p className="ztdl-p mb-6 block">
|
||||||
|
Setup your user to authenticate with passkeys.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Alert type={AlertType.INFO}>
|
||||||
|
A passkey is an authentication method on a device like your fingerprint,
|
||||||
|
Apple FaceID or similar.
|
||||||
|
</Alert>
|
||||||
|
|
||||||
{!sessionFactors && (
|
{!sessionFactors && (
|
||||||
<div className="py-4">
|
<div className="py-4">
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export async function PUT(request: NextRequest) {
|
|||||||
loginName: session.factors?.user?.loginName ?? "",
|
loginName: session.factors?.user?.loginName ?? "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log("new token", recent.token, newCookie.token);
|
||||||
|
|
||||||
return updateSessionCookie(sessionCookie.id, newCookie)
|
return updateSessionCookie(sessionCookie.id, newCookie)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return NextResponse.json({ factors: session.factors });
|
return NextResponse.json({ factors: session.factors });
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
DeleteSessionResponse,
|
DeleteSessionResponse,
|
||||||
VerifyPasskeyRegistrationResponse,
|
VerifyPasskeyRegistrationResponse,
|
||||||
} from "@zitadel/server";
|
} from "@zitadel/server";
|
||||||
|
import { Metadata } from "nice-grpc";
|
||||||
|
|
||||||
export const zitadelConfig: ZitadelServerOptions = {
|
export const zitadelConfig: ZitadelServerOptions = {
|
||||||
name: "zitadel login",
|
name: "zitadel login",
|
||||||
@@ -185,24 +186,8 @@ export async function setEmail(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
const bearerTokenMetadata = (token: string) =>
|
||||||
*
|
new Metadata({ authorization: `Bearer ${token}` });
|
||||||
* @param server
|
|
||||||
* @param userId the id of the user where the email should be set
|
|
||||||
* @returns the newly set email
|
|
||||||
*/
|
|
||||||
export async function registerPasskey(
|
|
||||||
server: ZitadelServer,
|
|
||||||
userId: string
|
|
||||||
): Promise<any> {
|
|
||||||
const userservice = user.getUser(server);
|
|
||||||
return userservice.registerPasskey(
|
|
||||||
{
|
|
||||||
userId,
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -214,22 +199,22 @@ export async function createPasskeyRegistrationLink(
|
|||||||
userId: string,
|
userId: string,
|
||||||
sessionToken: string
|
sessionToken: string
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
// this actions will be made from the currently seleected user
|
// this actions will be made from the currently seleected user
|
||||||
const zitadelConfig: ZitadelServerOptions = {
|
// const zitadelConfig: ZitadelServerOptions = {
|
||||||
name: "zitadel login",
|
// name: "zitadel login",
|
||||||
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
// apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||||
token: `${sessionToken}`,
|
// token: "",
|
||||||
};
|
// };
|
||||||
|
|
||||||
const server: ZitadelServer = initializeServer(zitadelConfig);
|
|
||||||
|
|
||||||
|
// const authserver: ZitadelServer = initializeServer(zitadelConfig);
|
||||||
|
// console.log("server", authserver);
|
||||||
const userservice = user.getUser(server);
|
const userservice = user.getUser(server);
|
||||||
return userservice.createPasskeyRegistrationLink(
|
return userservice.createPasskeyRegistrationLink(
|
||||||
{
|
{
|
||||||
userId,
|
userId,
|
||||||
// returnCode: new ReturnPasskeyRegistrationCode(),
|
returnCode: {},
|
||||||
},
|
}
|
||||||
{}
|
// { metadata: bearerTokenMetadata(sessionToken) }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,4 +242,34 @@ export async function verifyPasskeyRegistration(
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param server
|
||||||
|
* @param userId the id of the user where the email should be set
|
||||||
|
* @returns the newly set email
|
||||||
|
*/
|
||||||
|
export async function registerPasskey(
|
||||||
|
userId: string,
|
||||||
|
sessionToken: string
|
||||||
|
): Promise<any> {
|
||||||
|
// this actions will be made from the currently seleected user
|
||||||
|
const zitadelConfig: ZitadelServerOptions = {
|
||||||
|
name: "zitadel login",
|
||||||
|
apiUrl: process.env.ZITADEL_API_URL ?? "",
|
||||||
|
token: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
const authserver: ZitadelServer = initializeServer(zitadelConfig);
|
||||||
|
console.log("server", authserver);
|
||||||
|
const userservice = user.getUser(server);
|
||||||
|
return userservice.registerPasskey(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
// returnCode: new ReturnPasskeyRegistrationCode(),
|
||||||
|
},
|
||||||
|
{ metadata: bearerTokenMetadata(sessionToken) }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export { server };
|
export { server };
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
|
type?: AlertType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Alert({ children }: Props) {
|
export enum AlertType {
|
||||||
|
ALERT,
|
||||||
|
INFO,
|
||||||
|
}
|
||||||
|
|
||||||
|
const yellow =
|
||||||
|
"border-yellow-600/40 dark:border-yellow-500/20 bg-yellow-200/30 text-yellow-600 dark:bg-yellow-700/20 dark:text-yellow-200";
|
||||||
|
const red =
|
||||||
|
"border-red-600/40 dark:border-red-500/20 bg-red-200/30 text-red-600 dark:bg-red-700/20 dark:text-red-200";
|
||||||
|
const neutral =
|
||||||
|
"border-divider-light dark:border-divider-dark bg-black/5 text-gray-600 dark:bg-white/10 dark:text-gray-200";
|
||||||
|
|
||||||
|
export default function Alert({ children, type = AlertType.ALERT }: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row items-center justify-center border border-yellow-600/40 dark:border-yellow-500/20 bg-yellow-200/30 text-yellow-600 dark:bg-yellow-700/20 dark:text-yellow-200 rounded-md py-2 scroll-px-40">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
"flex flex-row items-center justify-center border rounded-md py-2 pr-2 scroll-px-40",
|
||||||
|
{
|
||||||
|
[yellow]: type === AlertType.ALERT,
|
||||||
|
[neutral]: type === AlertType.INFO,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
<ExclamationTriangleIcon className="flex-shrink-0 h-5 w-5 mr-2 ml-2" />
|
<ExclamationTriangleIcon className="flex-shrink-0 h-5 w-5 mr-2 ml-2" />
|
||||||
<span className="text-center text-sm">{children}</span>
|
<span className="text-center text-sm">{children}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
14
apps/login/ui/Info.tsx
Normal file
14
apps/login/ui/Info.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: React.ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Alert({ children }: Props) {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-row items-center justify-center border border-yellow-600/40 dark:border-yellow-500/20 bg-yellow-200/30 text-yellow-600 dark:bg-yellow-700/20 dark:text-yellow-200 rounded-md py-2 scroll-px-40">
|
||||||
|
<ExclamationTriangleIcon className="flex-shrink-0 h-5 w-5 mr-2 ml-2" />
|
||||||
|
<span className="text-center text-sm">{children}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import { createChannel, createClientFactory } from "nice-grpc";
|
import { createChannel, createClientFactory } from "nice-grpc";
|
||||||
import {
|
|
||||||
SettingsServiceClient,
|
|
||||||
SettingsServiceDefinition,
|
|
||||||
} from "./proto/server/zitadel/settings/v2alpha/settings_service";
|
|
||||||
import { authMiddleware } from "./middleware";
|
import { authMiddleware } from "./middleware";
|
||||||
import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions";
|
import { CompatServiceDefinition } from "nice-grpc/lib/service-definitions";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user