diff --git a/apps/login/app/(login)/accounts/page.tsx b/apps/login/app/(login)/accounts/page.tsx index ed8e68d523d..cf2e0037e9c 100644 --- a/apps/login/app/(login)/accounts/page.tsx +++ b/apps/login/app/(login)/accounts/page.tsx @@ -22,6 +22,8 @@ async function loadSessions(): Promise { export default async function Page() { let sessions = await loadSessions(); + + console.log(sessions); return (

Accounts

diff --git a/apps/login/app/(login)/passkey/login/page.tsx b/apps/login/app/(login)/passkey/login/page.tsx index a48578e6596..dfd8ac3658c 100644 --- a/apps/login/app/(login)/passkey/login/page.tsx +++ b/apps/login/app/(login)/passkey/login/page.tsx @@ -21,6 +21,8 @@ export default async function Page({ return response.session; } }); + + console.log(recent); } const title = !!prompt ? "Authenticate with a passkey" diff --git a/apps/login/app/methods/route.ts b/apps/login/app/methods/route.ts new file mode 100644 index 00000000000..68a73b45acd --- /dev/null +++ b/apps/login/app/methods/route.ts @@ -0,0 +1,114 @@ +import { + createSession, + getSession, + listAuthenticationMethodTypes, + server, +} from "#/lib/zitadel"; +import { + SessionCookie, + addSessionToCookie, + getSessionCookieById, +} from "#/utils/cookies"; +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(request: NextRequest) { + const { searchParams } = new URL(request.url); + const sessionId = searchParams.get("sessionId"); + if (sessionId) { + const sessionCookie = await getSessionCookieById(sessionId); + + const session = await getSession( + server, + sessionCookie.id, + sessionCookie.token + ); + + const userId = session?.session?.factors?.user?.id; + + if (userId) { + return listAuthenticationMethodTypes(userId) + .then((methods) => { + return NextResponse.json(methods); + }) + .catch((error) => { + return NextResponse.json(error, { status: 500 }); + }); + } else { + return NextResponse.json( + { details: "could not get session" }, + { status: 500 } + ); + } + } else { + return NextResponse.json({}, { status: 400 }); + } +} + +export async function POST(request: NextRequest) { + const body = await request.json(); + if (body) { + const { loginName } = body; + + const domain: string = request.nextUrl.hostname; + + const createdSession = await createSession( + server, + loginName, + undefined, + domain + ); + + if (createdSession) { + return getSession( + server, + createdSession.sessionId, + createdSession.sessionToken + ).then((response) => { + if (response?.session && response.session?.factors?.user?.loginName) { + const userId = response?.session?.factors?.user?.id; + + const sessionCookie: SessionCookie = { + id: createdSession.sessionId, + token: createdSession.sessionToken, + changeDate: response.session.changeDate?.toString() ?? "", + loginName: response.session?.factors?.user?.loginName ?? "", + }; + return addSessionToCookie(sessionCookie) + .then(() => { + return listAuthenticationMethodTypes(userId) + .then((methods) => { + return NextResponse.json({ + authMethodTypes: methods.authMethodTypes, + sessionId: createdSession.sessionId, + factors: response?.session?.factors, + }); + }) + .catch((error) => { + return NextResponse.json(error, { status: 500 }); + }); + }) + .catch((error) => { + return NextResponse.json( + { + details: "could not add session to cookie", + }, + { status: 500 } + ); + }); + } else { + return NextResponse.json( + { + details: + "could not get session or session does not have loginName", + }, + { status: 500 } + ); + } + }); + } else { + return NextResponse.error(); + } + } else { + return NextResponse.error(); + } +} diff --git a/apps/login/lib/zitadel.ts b/apps/login/lib/zitadel.ts index 9322a97e12b..10ad3b1fc96 100644 --- a/apps/login/lib/zitadel.ts +++ b/apps/login/lib/zitadel.ts @@ -265,4 +265,19 @@ export async function registerPasskey( }); } +/** + * + * @param server + * @param userId the id of the user where the email should be set + * @returns the newly set email + */ +export async function listAuthenticationMethodTypes( + userId: string +): Promise { + const userservice = user.getUser(server); + return userservice.listAuthenticationMethodTypes({ + userId, + }); +} + export { server }; diff --git a/apps/login/ui/UsernameForm.tsx b/apps/login/ui/UsernameForm.tsx index 1e63dcb560c..606b4f06c5c 100644 --- a/apps/login/ui/UsernameForm.tsx +++ b/apps/login/ui/UsernameForm.tsx @@ -6,6 +6,10 @@ import { TextInput } from "./Input"; import { useForm } from "react-hook-form"; import { useRouter } from "next/navigation"; import { Spinner } from "./Spinner"; +import { + ListAuthenticationMethodTypesResponse, + AuthenticationMethodType, +} from "@zitadel/server"; type Inputs = { loginName: string; @@ -18,11 +22,11 @@ export default function UsernameForm() { const [loading, setLoading] = useState(false); - const router = useRouter(); - - async function submitUsername(values: Inputs) { + async function submitUsernameAndGetAuthenticationMethods( + values: Inputs + ): Promise { setLoading(true); - const res = await fetch("/session", { + const res = await fetch("/methods", { method: "POST", headers: { "Content-Type": "application/json", @@ -34,18 +38,20 @@ export default function UsernameForm() { setLoading(false); if (!res.ok) { - throw new Error("Failed to set user"); + throw new Error("Failed to load authentication methods"); } return res.json(); } function submitUsernameAndContinue(value: Inputs): Promise { - return submitUsername(value).then(({ factors }) => { - return router.push( - `/password?` + - new URLSearchParams({ loginName: `${factors.user.loginName}` }) - ); - }); + return submitUsernameAndGetAuthenticationMethods(value).then( + ({ factors, sessionId, authMethodTypes }) => { + console.log(factors, sessionId, authMethodTypes); + if (authMethodTypes.length === 1) { + } else { + } + } + ); } const { errors } = formState; diff --git a/packages/zitadel-server/src/index.ts b/packages/zitadel-server/src/index.ts index ba0fbb49c9c..8a997393c35 100644 --- a/packages/zitadel-server/src/index.ts +++ b/packages/zitadel-server/src/index.ts @@ -35,6 +35,9 @@ export { RegisterPasskeyResponse, CreatePasskeyRegistrationLinkResponse, CreatePasskeyRegistrationLinkRequest, + ListAuthenticationMethodTypesResponse, + ListAuthenticationMethodTypesRequest, + AuthenticationMethodType, } from "./proto/server/zitadel/user/v2alpha/user_service"; export { SetHumanPasswordResponse,