loginname, password org context

This commit is contained in:
peintnermax
2024-03-25 13:39:23 +01:00
parent f6e9f69859
commit a9d0752b5f
8 changed files with 182 additions and 46 deletions

View File

@@ -40,8 +40,7 @@ export default async function Page({
const loginSettings = await getLoginSettings(server, organization);
const legal = await getLegalAndSupportSettings(server);
// TODO if org idps should be shown replace emptystring with the orgId.
const identityProviders = await getIdentityProviders(server, "");
const identityProviders = await getIdentityProviders(server, organization);
const host = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`

View File

@@ -9,7 +9,7 @@ export default async function Page({
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
const { loginName, prompt } = searchParams;
const { loginName, prompt, organization } = searchParams;
const sessionFactors = await loadSession(loginName);

View File

@@ -9,11 +9,15 @@ export default async function Page({
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
const { loginName, promptPasswordless, authRequestId, alt } = searchParams;
const sessionFactors = await loadSession(loginName);
const { loginName, organization, promptPasswordless, authRequestId, alt } =
searchParams;
const sessionFactors = await loadSession(loginName, organization);
async function loadSession(loginName?: string) {
const recent = await getMostRecentCookieWithLoginname(loginName);
async function loadSession(loginName?: string, organization?: string) {
const recent = await getMostRecentCookieWithLoginname(
loginName,
organization
);
return getSession(server, recent.id, recent.token).then((response) => {
if (response?.session) {

View File

@@ -1,5 +1,9 @@
import { listAuthenticationMethodTypes, listUsers } from "#/lib/zitadel";
import { createSessionAndUpdateCookie } from "#/utils/session";
import {
createSessionAndUpdateCookie,
createSessionForUserIdAndUpdateCookie,
} from "#/utils/session";
import { U } from "@zitadel/server/dist/index-79b5dba4";
import { NextRequest, NextResponse } from "next/server";
export async function POST(request: NextRequest) {
@@ -7,36 +11,56 @@ export async function POST(request: NextRequest) {
if (body) {
const { loginName, authRequestId, organization } = body;
// TODO - search for users with org
// return listUsers(loginName).then((users) => {
// if (users.details && users.details.totalResult == 1) {
// }
return createSessionAndUpdateCookie(
console.log(
"loginName",
loginName,
undefined,
undefined,
authRequestId
)
.then((session) => {
if (session.factors?.user?.id) {
return listAuthenticationMethodTypes(session.factors?.user?.id)
.then((methods) => {
return NextResponse.json({
authMethodTypes: methods.authMethodTypes,
sessionId: session.id,
factors: session.factors,
});
})
.catch((error) => {
return NextResponse.json(error, { status: 500 });
});
} else {
throw { details: "No user id found in session" };
}
})
.catch((error) => {
return NextResponse.json(error, { status: 500 });
});
// });
"authRequestId",
authRequestId,
"organization",
organization
);
return listUsers(loginName, organization).then((users) => {
console.log("users", users);
if (
users.details &&
users.details.totalResult == 1 &&
users.result[0].userId
) {
const userId = users.result[0].userId;
return createSessionForUserIdAndUpdateCookie(
userId,
undefined,
undefined,
authRequestId
)
.then((session) => {
console.log(session);
if (session.factors?.user?.id) {
return listAuthenticationMethodTypes(session.factors?.user?.id)
.then((methods) => {
return NextResponse.json({
authMethodTypes: methods.authMethodTypes,
sessionId: session.id,
factors: session.factors,
});
})
.catch((error) => {
return NextResponse.json(error, { status: 500 });
});
} else {
throw { details: "No user id found in session" };
}
})
.catch((error) => {
return NextResponse.json(error, { status: 500 });
});
} else {
return NextResponse.json(
{ message: "Could not find user" },
{ status: 404 }
);
}
});
} else {
return NextResponse.error();
}

View File

@@ -135,6 +135,38 @@ export async function createSessionForLoginname(
);
}
export async function createSessionForUserId(
server: ZitadelServer,
userId: string,
password: string | undefined,
challenges: RequestChallenges | undefined
): Promise<CreateSessionResponse | undefined> {
const sessionService = session.getSession(server);
return password
? sessionService.createSession(
{
checks: { user: { userId }, password: { password } },
challenges,
// lifetime: {
// seconds: 300,
// nanos: 0,
// },
},
{}
)
: sessionService.createSession(
{
checks: { user: { userId } },
challenges,
// lifetime: {
// seconds: 300,
// nanos: 0,
// },
},
{}
);
}
export async function createSessionForUserIdAndIdpIntent(
server: ZitadelServer,
userId: string,
@@ -247,10 +279,13 @@ export async function addHumanUser(
});
}
export async function listUsers(userName: string): Promise<ListUsersResponse> {
// TODO limit for organization
export async function listUsers(
userName: string,
organizationId: string
): Promise<ListUsersResponse> {
const userService = user.getUser(server);
console.log("listUsers", userName, organizationId);
return userService.listUsers(
{
queries: [
@@ -259,6 +294,11 @@ export async function listUsers(userName: string): Promise<ListUsersResponse> {
userName,
method: TextQueryMethod.TEXT_QUERY_METHOD_EQUALS,
},
organizationIdQuery: organizationId
? {
organizationId,
}
: undefined,
},
],
},

View File

@@ -3,7 +3,7 @@
import { useEffect, useState } from "react";
import { Button, ButtonVariants } from "./Button";
import { TextInput } from "./Input";
import { SubmitHandler, useForm } from "react-hook-form";
import { useForm } from "react-hook-form";
import { useRouter } from "next/navigation";
import { Spinner } from "./Spinner";
import { LoginSettings } from "@zitadel/server";
@@ -51,12 +51,16 @@ export default function UsernameForm({
body.organization = organization;
}
if (authRequestId) {
body.authRequestId = authRequestId;
}
const res = await fetch("/api/loginname", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(authRequestId ? { ...body, authRequestId } : body),
body: JSON.stringify(body),
});
setLoading(false);
@@ -78,7 +82,13 @@ export default function UsernameForm({
const method = response.authMethodTypes[0];
switch (method) {
case 1: // user has only password as auth method
const paramsPassword: any = { loginName: values.loginName };
const paramsPassword: any = {
loginName: response.factors.user.loginName,
};
if (organization) {
paramsPassword.organization = organization;
}
if (loginSettings?.passkeysType === 1) {
paramsPassword.promptPasswordless = `true`; // PasskeysType.PASSKEYS_TYPE_ALLOWED,

View File

@@ -6,6 +6,7 @@ export type SessionCookie = {
id: string;
token: string;
loginName: string;
organization: string;
creationDate: string;
expirationDate: string;
changeDate: string;
@@ -226,17 +227,24 @@ export async function getAllSessions(
* @returns most recent session
*/
export async function getMostRecentCookieWithLoginname(
loginName?: string
loginName?: string,
organization?: string
): Promise<any> {
const cookiesList = cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
const sessions: SessionCookie[] = JSON.parse(stringifiedCookie?.value);
const filtered = sessions.filter((cookie) => {
let filtered = sessions.filter((cookie) => {
return !!loginName ? cookie.loginName === loginName : true;
});
if (organization) {
filtered = filtered.filter((cookie) => {
return cookie.organization === organization;
});
}
const latest =
filtered && filtered.length
? filtered.reduce((prev, current) => {

View File

@@ -2,6 +2,7 @@
import {
createSessionForLoginname,
createSessionForUserId,
createSessionForUserIdAndIdpIntent,
getSession,
server,
@@ -40,7 +41,54 @@ export async function createSessionAndUpdateCookie(
creationDate: response.session.creationDate?.toString() ?? "",
expirationDate: (response.session.expirationDate ?? "")?.toString(),
changeDate: response.session.changeDate?.toString() ?? "",
loginName: response.session?.factors?.user?.loginName ?? "",
loginName: response.session.factors.user.loginName ?? "",
organization: response.session.factors.user.organizationId ?? "",
};
if (authRequestId) {
sessionCookie.authRequestId = authRequestId;
}
return addSessionToCookie(sessionCookie).then(() => {
return response.session as Session;
});
} else {
throw "could not get session or session does not have loginName";
}
});
} else {
throw "Could not create session";
}
}
export async function createSessionForUserIdAndUpdateCookie(
userId: string,
password: string | undefined,
challenges: RequestChallenges | undefined,
authRequestId: string | undefined
): Promise<Session> {
const createdSession = await createSessionForUserId(
server,
userId,
password,
challenges
);
if (createdSession) {
return getSession(
server,
createdSession.sessionId,
createdSession.sessionToken
).then((response) => {
if (response?.session && response.session?.factors?.user?.loginName) {
const sessionCookie: SessionCookie = {
id: createdSession.sessionId,
token: createdSession.sessionToken,
creationDate: response.session.creationDate?.toString() ?? "",
expirationDate: (response.session.expirationDate ?? "")?.toString(),
changeDate: response.session.changeDate?.toString() ?? "",
loginName: response.session.factors.user.loginName ?? "",
organization: response.session.factors.user.organizationId ?? "",
};
if (authRequestId) {
@@ -86,7 +134,8 @@ export async function createSessionForIdpAndUpdateCookie(
creationDate: response.session.creationDate?.toString() ?? "",
expirationDate: (response.session.expirationDate ?? "")?.toString(),
changeDate: response.session.changeDate?.toString() ?? "",
loginName: response.session?.factors?.user?.loginName ?? "",
loginName: response.session.factors.user.loginName ?? "",
organization: response.session.factors.user.organizationId ?? "",
};
if (authRequestId) {
@@ -132,6 +181,7 @@ export async function setSessionAndUpdateCookie(
expirationDate: recentCookie.expirationDate,
changeDate: updatedSession.details?.changeDate?.toString() ?? "",
loginName: recentCookie.loginName,
organization: recentCookie.organization,
};
if (authRequestId) {
@@ -154,6 +204,7 @@ export async function setSessionAndUpdateCookie(
expirationDate: sessionCookie.expirationDate,
changeDate: session.changeDate?.toString() ?? "",
loginName: session.factors?.user?.loginName ?? "",
organization: session.factors?.user?.organizationId ?? "",
};
if (sessionCookie.authRequestId) {