Merge pull request #386 from zitadel/user-agent

feat: generate user agent fingerprint id
This commit is contained in:
Max Peintner
2025-03-12 16:41:10 +01:00
committed by GitHub
41 changed files with 124 additions and 201 deletions

View File

@@ -56,7 +56,8 @@
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-hook-form": "7.39.5", "react-hook-form": "7.39.5",
"swr": "^2.2.0", "swr": "^2.2.0",
"tinycolor2": "1.4.2" "tinycolor2": "1.4.2",
"uuid": "^11.1.0"
}, },
"devDependencies": { "devDependencies": {
"@bufbuild/buf": "^1.46.0", "@bufbuild/buf": "^1.46.0",

View File

@@ -19,7 +19,6 @@ async function loadSessions({ serviceUrl }: { serviceUrl: string }) {
if (ids && ids.length) { if (ids && ids.length) {
const response = await listSessions({ const response = await listSessions({
serviceUrl, serviceUrl,
ids: ids.filter((id) => !!id) as string[], ids: ids.filter((id) => !!id) as string[],
}); });
return response?.sessions ?? []; return response?.sessions ?? [];
@@ -56,7 +55,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization: organization ?? defaultOrganization, organization: organization ?? defaultOrganization,
}); });

View File

@@ -49,7 +49,6 @@ export default async function Page(props: {
return listAuthenticationMethodTypes({ return listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId, userId,
}).then((methods) => { }).then((methods) => {
return getUserByID({ serviceUrl, userId }).then((user) => { return getUserByID({ serviceUrl, userId }).then((user) => {
@@ -74,7 +73,6 @@ export default async function Page(props: {
) { ) {
return loadMostRecentSession({ return loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -92,15 +90,10 @@ export default async function Page(props: {
const recent = await getSessionCookieById({ sessionId, organization }); const recent = await getSessionCookieById({ sessionId, organization });
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((sessionResponse) => { }).then((sessionResponse) => {
return getAuthMethodsAndUser( return getAuthMethodsAndUser(serviceUrl, sessionResponse.session);
serviceUrl,
sessionResponse.session,
);
}); });
} }
@@ -110,19 +103,16 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization: sessionWithData.factors?.user?.organizationId, organization: sessionWithData.factors?.user?.organizationId,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: sessionWithData.factors?.user?.organizationId, organization: sessionWithData.factors?.user?.organizationId,
}); });
const identityProviders = await getActiveIdentityProviders({ const identityProviders = await getActiveIdentityProviders({
serviceUrl, serviceUrl,
orgId: sessionWithData.factors?.user?.organizationId, orgId: sessionWithData.factors?.user?.organizationId,
linking_allowed: true, linking_allowed: true,
}).then((resp) => { }).then((resp) => {

View File

@@ -29,13 +29,11 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -54,7 +52,6 @@ export default async function Page(props: {
if (userId) { if (userId) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId, userId,
}); });
if (userResponse) { if (userResponse) {
@@ -70,7 +67,6 @@ export default async function Page(props: {
const authMethodsResponse = await listAuthenticationMethodTypes({ const authMethodsResponse = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId, userId,
}); });
if (authMethodsResponse.authMethodTypes) { if (authMethodsResponse.authMethodTypes) {

View File

@@ -44,7 +44,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -54,7 +53,6 @@ export default async function Page(props: {
const intent = await retrieveIDPIntent({ const intent = await retrieveIDPIntent({
serviceUrl, serviceUrl,
id, id,
token, token,
}); });
@@ -79,7 +77,6 @@ export default async function Page(props: {
const idp = await getIDPByID({ const idp = await getIDPByID({
serviceUrl, serviceUrl,
id: idpInformation.idpId, id: idpInformation.idpId,
}); });
const options = idp?.config?.options; const options = idp?.config?.options;
@@ -100,7 +97,6 @@ export default async function Page(props: {
try { try {
idpLink = await addIDPLink({ idpLink = await addIDPLink({
serviceUrl, serviceUrl,
idp: { idp: {
id: idpInformation.idpId, id: idpInformation.idpId,
userId: idpInformation.userId, userId: idpInformation.userId,
@@ -145,7 +141,6 @@ export default async function Page(props: {
} else { } else {
foundUser = await listUsers({ foundUser = await listUsers({
serviceUrl, serviceUrl,
userName: idpInformation.userName, userName: idpInformation.userName,
email, email,
}).then((response) => { }).then((response) => {
@@ -158,7 +153,6 @@ export default async function Page(props: {
try { try {
idpLink = await addIDPLink({ idpLink = await addIDPLink({
serviceUrl, serviceUrl,
idp: { idp: {
id: idpInformation.idpId, id: idpInformation.idpId,
userId: idpInformation.userId, userId: idpInformation.userId,
@@ -201,7 +195,6 @@ export default async function Page(props: {
// this just returns orgs where the suffix is set as primary domain // this just returns orgs where the suffix is set as primary domain
const orgs = await getOrgsByDomain({ const orgs = await getOrgsByDomain({
serviceUrl, serviceUrl,
domain: suffix, domain: suffix,
}); });
const orgToCheckForDiscovery = const orgToCheckForDiscovery =
@@ -209,7 +202,6 @@ export default async function Page(props: {
const orgLoginSettings = await getLoginSettings({ const orgLoginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: orgToCheckForDiscovery, organization: orgToCheckForDiscovery,
}); });
if (orgLoginSettings?.allowDomainDiscovery) { if (orgLoginSettings?.allowDomainDiscovery) {
@@ -230,7 +222,6 @@ export default async function Page(props: {
const newUser = await addHuman({ const newUser = await addHuman({
serviceUrl, serviceUrl,
request: userData, request: userData,
}); });

View File

@@ -20,7 +20,6 @@ export default async function Page(props: {
const identityProviders = await getActiveIdentityProviders({ const identityProviders = await getActiveIdentityProviders({
serviceUrl, serviceUrl,
orgId: organization, orgId: organization,
}).then((resp) => { }).then((resp) => {
return resp.identityProviders; return resp.identityProviders;
@@ -28,7 +27,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -34,19 +34,16 @@ export default async function Page(props: {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const passwordComplexitySettings = await getPasswordComplexitySettings({ const passwordComplexitySettings = await getPasswordComplexitySettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -32,7 +32,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -41,7 +40,6 @@ export default async function Page(props: {
if (userId) { if (userId) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId, userId,
}); });
if (userResponse) { if (userResponse) {

View File

@@ -40,19 +40,16 @@ export default async function Page(props: {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: organization ?? defaultOrganization, organization: organization ?? defaultOrganization,
}); });
const contextLoginSettings = await getLoginSettings({ const contextLoginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const identityProviders = await getActiveIdentityProviders({ const identityProviders = await getActiveIdentityProviders({
serviceUrl, serviceUrl,
orgId: organization ?? defaultOrganization, orgId: organization ?? defaultOrganization,
}).then((resp) => { }).then((resp) => {
return resp.identityProviders; return resp.identityProviders;
@@ -60,7 +57,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization: organization ?? defaultOrganization, organization: organization ?? defaultOrganization,
}); });

View File

@@ -38,7 +38,6 @@ export default async function Page(props: {
) { ) {
return loadMostRecentSession({ return loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -47,7 +46,6 @@ export default async function Page(props: {
if (session && session.factors?.user?.id) { if (session && session.factors?.user?.id) {
return listAuthenticationMethodTypes({ return listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}).then((methods) => { }).then((methods) => {
return { return {
@@ -67,14 +65,12 @@ export default async function Page(props: {
const recent = await getSessionCookieById({ sessionId, organization }); const recent = await getSessionCookieById({ sessionId, organization });
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((response) => { }).then((response) => {
if (response?.session && response.session.factors?.user?.id) { if (response?.session && response.session.factors?.user?.id) {
return listAuthenticationMethodTypes({ return listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: response.session.factors.user.id, userId: response.session.factors.user.id,
}).then((methods) => { }).then((methods) => {
return { return {
@@ -88,7 +84,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -61,7 +61,6 @@ export default async function Page(props: {
return listAuthenticationMethodTypes({ return listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId, userId,
}).then((methods) => { }).then((methods) => {
return getUserByID({ serviceUrl, userId }).then((user) => { return getUserByID({ serviceUrl, userId }).then((user) => {
@@ -85,7 +84,6 @@ export default async function Page(props: {
) { ) {
return loadMostRecentSession({ return loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -108,12 +106,10 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: sessionWithData.factors?.user?.organizationId, organization: sessionWithData.factors?.user?.organizationId,
}); });

View File

@@ -47,7 +47,6 @@ export default async function Page(props: {
? await loadSessionById(serviceUrl, sessionId, organization) ? await loadSessionById(serviceUrl, sessionId, organization)
: await loadMostRecentSession({ : await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { loginName, organization }, sessionParams: { loginName, organization },
}); });
@@ -59,7 +58,6 @@ export default async function Page(props: {
const recent = await getSessionCookieById({ sessionId, organization }); const recent = await getSessionCookieById({ sessionId, organization });
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((response) => { }).then((response) => {
@@ -72,13 +70,11 @@ export default async function Page(props: {
// email links do not come with organization, thus we need to use the session's organization // email links do not come with organization, thus we need to use the session's organization
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization: organization ?? session?.factors?.user?.organizationId, organization: organization ?? session?.factors?.user?.organizationId,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: organization ?? session?.factors?.user?.organizationId, organization: organization ?? session?.factors?.user?.organizationId,
}); });

View File

@@ -38,18 +38,15 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const session = await loadMostRecentSession({ const session = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -61,7 +58,6 @@ export default async function Page(props: {
if (method === "time-based") { if (method === "time-based") {
await registerTOTP({ await registerTOTP({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}) })
.then((resp) => { .then((resp) => {
@@ -76,7 +72,6 @@ export default async function Page(props: {
// does not work // does not work
await addOTPSMS({ await addOTPSMS({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}).catch((error) => { }).catch((error) => {
error = new Error("Could not add OTP via SMS"); error = new Error("Could not add OTP via SMS");
@@ -85,7 +80,6 @@ export default async function Page(props: {
// works // works
await addOTPEmail({ await addOTPEmail({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}).catch((error) => { }).catch((error) => {
error = new Error("Could not add OTP via Email"); error = new Error("Could not add OTP via Email");

View File

@@ -27,7 +27,6 @@ export default async function Page(props: {
? await loadSessionById(serviceUrl, sessionId, organization) ? await loadSessionById(serviceUrl, sessionId, organization)
: await loadMostRecentSession({ : await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { loginName, organization }, sessionParams: { loginName, organization },
}); });
@@ -39,7 +38,6 @@ export default async function Page(props: {
const recent = await getSessionCookieById({ sessionId, organization }); const recent = await getSessionCookieById({ sessionId, organization });
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((response) => { }).then((response) => {
@@ -51,7 +49,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -23,7 +23,6 @@ export default async function Page(props: {
const session = await loadMostRecentSession({ const session = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -32,7 +31,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -28,7 +28,6 @@ export default async function Page(props: {
// also allow no session to be found (ignoreUnkownUsername) // also allow no session to be found (ignoreUnkownUsername)
const sessionFactors = await loadMostRecentSession({ const sessionFactors = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -37,19 +36,16 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const passwordComplexity = await getPasswordComplexitySettings({ const passwordComplexity = await getPasswordComplexitySettings({
serviceUrl, serviceUrl,
organization: sessionFactors?.factors?.user?.organizationId, organization: sessionFactors?.factors?.user?.organizationId,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: sessionFactors?.factors?.user?.organizationId, organization: sessionFactors?.factors?.user?.organizationId,
}); });

View File

@@ -43,7 +43,6 @@ export default async function Page(props: {
try { try {
sessionFactors = await loadMostRecentSession({ sessionFactors = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -56,12 +55,10 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization: organization ?? defaultOrganization, organization: organization ?? defaultOrganization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: organization ?? defaultOrganization, organization: organization ?? defaultOrganization,
}); });

View File

@@ -34,7 +34,6 @@ export default async function Page(props: {
if (loginName) { if (loginName) {
session = await loadMostRecentSession({ session = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -44,19 +43,16 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const passwordComplexity = await getPasswordComplexitySettings({ const passwordComplexity = await getPasswordComplexitySettings({
serviceUrl, serviceUrl,
organization: session?.factors?.user?.organizationId, organization: session?.factors?.user?.organizationId,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -65,7 +61,6 @@ export default async function Page(props: {
if (userId) { if (userId) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId, userId,
}); });
user = userResponse.user; user = userResponse.user;

View File

@@ -35,24 +35,20 @@ export default async function Page(props: {
const legal = await getLegalAndSupportSettings({ const legal = await getLegalAndSupportSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const passwordComplexitySettings = await getPasswordComplexitySettings({ const passwordComplexitySettings = await getPasswordComplexitySettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -37,24 +37,20 @@ export default async function Page(props: {
const legal = await getLegalAndSupportSettings({ const legal = await getLegalAndSupportSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const passwordComplexitySettings = await getPasswordComplexitySettings({ const passwordComplexitySettings = await getPasswordComplexitySettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -33,7 +33,6 @@ async function loadSession(
if (requestId && requestId.startsWith("oidc_")) { if (requestId && requestId.startsWith("oidc_")) {
return createCallback({ return createCallback({
serviceUrl, serviceUrl,
req: create(CreateCallbackRequestSchema, { req: create(CreateCallbackRequestSchema, {
authRequestId: requestId, authRequestId: requestId,
callbackKind: { callbackKind: {
@@ -67,7 +66,6 @@ async function loadSession(
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((response) => { }).then((response) => {
@@ -86,16 +84,10 @@ export default async function Page(props: { searchParams: Promise<any> }) {
const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const { loginName, requestId, organization } = searchParams; const { loginName, requestId, organization } = searchParams;
const sessionFactors = await loadSession( const sessionFactors = await loadSession(serviceUrl, loginName, requestId);
serviceUrl,
loginName,
requestId,
);
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -103,7 +95,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
if (!requestId) { if (!requestId) {
loginSettings = await getLoginSettings({ loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
} }

View File

@@ -29,7 +29,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -37,7 +36,6 @@ export default async function Page(props: {
? await loadSessionById(serviceUrl, sessionId, organization) ? await loadSessionById(serviceUrl, sessionId, organization)
: await loadMostRecentSession({ : await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { loginName, organization }, sessionParams: { loginName, organization },
}); });
@@ -49,7 +47,6 @@ export default async function Page(props: {
const recent = await getSessionCookieById({ sessionId, organization }); const recent = await getSessionCookieById({ sessionId, organization });
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((response) => { }).then((response) => {

View File

@@ -23,7 +23,6 @@ export default async function Page(props: {
const sessionFactors = await loadMostRecentSession({ const sessionFactors = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -32,7 +31,6 @@ export default async function Page(props: {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });

View File

@@ -35,7 +35,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
const branding = await getBrandingSettings({ const branding = await getBrandingSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -51,7 +50,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
if ("loginName" in searchParams) { if ("loginName" in searchParams) {
sessionFactors = await loadMostRecentSession({ sessionFactors = await loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -86,7 +84,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId, userId,
}); });
if (userResponse) { if (userResponse) {

View File

@@ -159,7 +159,6 @@ export async function GET(request: NextRequest) {
if (orgDomain) { if (orgDomain) {
const orgs = await getOrgsByDomain({ const orgs = await getOrgsByDomain({
serviceUrl, serviceUrl,
domain: orgDomain, domain: orgDomain,
}); });
if (orgs.result && orgs.result.length === 1) { if (orgs.result && orgs.result.length === 1) {
@@ -367,7 +366,6 @@ export async function GET(request: NextRequest) {
try { try {
const { callbackUrl } = await createCallback({ const { callbackUrl } = await createCallback({
serviceUrl, serviceUrl,
req: create(CreateCallbackRequestSchema, { req: create(CreateCallbackRequestSchema, {
authRequestId: requestId.replace("oidc_", ""), authRequestId: requestId.replace("oidc_", ""),
callbackKind: { callbackKind: {

View File

@@ -0,0 +1,66 @@
import { create } from "@zitadel/client";
import {
UserAgent,
UserAgentSchema,
} from "@zitadel/proto/zitadel/session/v2/session_pb";
import { cookies, headers } from "next/headers";
import { userAgent } from "next/server";
import { v4 as uuidv4 } from "uuid";
export async function getFingerprintId() {
return uuidv4();
}
export async function setFingerprintIdCookie(fingerprintId: string) {
const cookiesList = await cookies();
return cookiesList.set({
name: "fingerprintId",
value: fingerprintId,
httpOnly: true,
path: "/",
maxAge: 31536000, // 1 year
});
}
export async function getFingerprintIdCookie() {
const cookiesList = await cookies();
return cookiesList.get("fingerprintId");
}
export async function getOrSetFingerprintId(): Promise<string> {
const cookie = await getFingerprintIdCookie();
if (cookie) {
return cookie.value;
}
const fingerprintId = await getFingerprintId();
await setFingerprintIdCookie(fingerprintId);
return fingerprintId;
}
export async function getUserAgent(): Promise<UserAgent> {
const _headers = await headers();
const fingerprintId = await getOrSetFingerprintId();
const { device, engine, os, browser } = userAgent({ headers: _headers });
const userAgentHeader = _headers.get("user-agent");
const userAgentHeaderValues = userAgentHeader?.split(",");
const deviceDescription = `${device?.type ? `${device.type},` : ""} ${device?.vendor ? `${device.vendor},` : ""} ${device.model ? `${device.model},` : ""} `;
const osDescription = `${os?.name ? `${os.name},` : ""} ${os?.version ? `${os.version},` : ""} `;
const engineDescription = `${engine?.name ? `${engine.name},` : ""} ${engine?.version ? `${engine.version},` : ""} `;
const browserDescription = `${browser?.name ? `${browser.name},` : ""} ${browser.version ? `${browser.version},` : ""} `;
const userAgentData: UserAgent = create(UserAgentSchema, {
ip: _headers.get("x-forwarded-for") ?? _headers.get("remoteAddress") ?? "",
header: { "user-agent": { values: userAgentHeaderValues } },
description: `${browserDescription}, ${deviceDescription}, ${engineDescription}, ${osDescription}`,
fingerprintId: fingerprintId,
});
return userAgentData;
}

View File

@@ -32,7 +32,6 @@ export async function setMyPassword({
const { session } = await getSession({ const { session } = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });

View File

@@ -46,24 +46,23 @@ const passwordAttemptsHandler = (error: ConnectError) => {
throw error; throw error;
}; };
export async function createSessionAndUpdateCookie( export async function createSessionAndUpdateCookie(command: {
checks: Checks, checks: Checks;
requestId: string | undefined, requestId: string | undefined;
lifetime?: Duration, lifetime?: Duration;
): Promise<Session> { }): Promise<Session> {
const _headers = await headers(); const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const createdSession = await createSessionFromChecks({ const createdSession = await createSessionFromChecks({
serviceUrl, serviceUrl,
checks, checks: command.checks,
lifetime, lifetime: command.lifetime,
}); });
if (createdSession) { if (createdSession) {
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: createdSession.sessionId, sessionId: createdSession.sessionId,
sessionToken: createdSession.sessionToken, sessionToken: createdSession.sessionToken,
}).then((response) => { }).then((response) => {
@@ -83,8 +82,8 @@ export async function createSessionAndUpdateCookie(
loginName: response.session.factors.user.loginName ?? "", loginName: response.session.factors.user.loginName ?? "",
}; };
if (requestId) { if (command.requestId) {
sessionCookie.requestId = requestId; sessionCookie.requestId = command.requestId;
} }
if (response.session.factors.user.organizationId) { if (response.session.factors.user.organizationId) {
@@ -118,7 +117,6 @@ export async function createSessionForIdpAndUpdateCookie(
const createdSession = await createSessionForUserIdAndIdpIntent({ const createdSession = await createSessionForUserIdAndIdpIntent({
serviceUrl, serviceUrl,
userId, userId,
idpIntent, idpIntent,
lifetime, lifetime,
@@ -139,7 +137,6 @@ export async function createSessionForIdpAndUpdateCookie(
const { session } = await getSession({ const { session } = await getSession({
serviceUrl, serviceUrl,
sessionId: createdSession.sessionId, sessionId: createdSession.sessionId,
sessionToken: createdSession.sessionToken, sessionToken: createdSession.sessionToken,
}); });
@@ -191,7 +188,6 @@ export async function setSessionAndUpdateCookie(
return setSession({ return setSession({
serviceUrl, serviceUrl,
sessionId: recentCookie.id, sessionId: recentCookie.id,
sessionToken: recentCookie.token, sessionToken: recentCookie.token,
challenges, challenges,
@@ -219,7 +215,6 @@ export async function setSessionAndUpdateCookie(
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}).then((response) => { }).then((response) => {

View File

@@ -62,6 +62,7 @@ export async function createNewSessionFromIdpIntent(
command: CreateNewSessionCommand, command: CreateNewSessionCommand,
) { ) {
const _headers = await headers(); const _headers = await headers();
const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { serviceUrl } = getServiceUrlFromHeaders(_headers);
const host = _headers.get("host"); const host = _headers.get("host");
@@ -75,7 +76,6 @@ export async function createNewSessionFromIdpIntent(
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
}); });
@@ -85,7 +85,6 @@ export async function createNewSessionFromIdpIntent(
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: userResponse.user.details?.resourceOwner, organization: userResponse.user.details?.resourceOwner,
}); });

View File

@@ -31,7 +31,6 @@ export async function inviteUser(command: InviteUserCommand) {
const human = await addHumanUser({ const human = await addHumanUser({
serviceUrl, serviceUrl,
email: command.email, email: command.email,
firstName: command.firstName, firstName: command.firstName,
lastName: command.lastName, lastName: command.lastName,

View File

@@ -43,7 +43,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const loginSettingsByContext = await getLoginSettings({ const loginSettingsByContext = await getLoginSettings({
serviceUrl, serviceUrl,
organization: command.organization, organization: command.organization,
}); });
@@ -53,7 +52,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
let searchUsersRequest: SearchUsersCommand = { let searchUsersRequest: SearchUsersCommand = {
serviceUrl, serviceUrl,
searchValue: command.loginName, searchValue: command.loginName,
organizationId: command.organization, organizationId: command.organization,
loginSettings: loginSettingsByContext, loginSettings: loginSettingsByContext,
@@ -75,7 +73,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const redirectUserToSingleIDPIfAvailable = async () => { const redirectUserToSingleIDPIfAvailable = async () => {
const identityProviders = await getActiveIdentityProviders({ const identityProviders = await getActiveIdentityProviders({
serviceUrl, serviceUrl,
orgId: command.organization, orgId: command.organization,
}).then((resp) => { }).then((resp) => {
return resp.identityProviders; return resp.identityProviders;
@@ -128,7 +125,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const redirectUserToIDP = async (userId: string) => { const redirectUserToIDP = async (userId: string) => {
const identityProviders = await listIDPLinks({ const identityProviders = await listIDPLinks({
serviceUrl, serviceUrl,
userId, userId,
}).then((resp) => { }).then((resp) => {
return resp.result; return resp.result;
@@ -147,7 +143,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const idp = await getIDPByID({ const idp = await getIDPByID({
serviceUrl, serviceUrl,
id: identityProviderId, id: identityProviderId,
}); });
@@ -199,7 +194,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const userLoginSettings = await getLoginSettings({ const userLoginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: user.details?.resourceOwner, organization: user.details?.resourceOwner,
}); });
@@ -241,10 +235,10 @@ export async function sendLoginname(command: SendLoginnameCommand) {
user: { search: { case: "userId", value: userId } }, user: { search: { case: "userId", value: userId } },
}); });
const session = await createSessionAndUpdateCookie( const session = await createSessionAndUpdateCookie({
checks, checks,
command.requestId, requestId: command.requestId,
); });
if (!session.factors?.user?.id) { if (!session.factors?.user?.id) {
return { error: "Could not create session for user" }; return { error: "Could not create session for user" };
@@ -257,7 +251,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const methods = await listAuthenticationMethodTypes({ const methods = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: session.factors?.user?.id, userId: session.factors?.user?.id,
}); });
@@ -416,7 +409,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
// this just returns orgs where the suffix is set as primary domain // this just returns orgs where the suffix is set as primary domain
const orgs = await getOrgsByDomain({ const orgs = await getOrgsByDomain({
serviceUrl, serviceUrl,
domain: suffix, domain: suffix,
}); });
const orgToCheckForDiscovery = const orgToCheckForDiscovery =
@@ -424,7 +416,6 @@ export async function sendLoginname(command: SendLoginnameCommand) {
const orgLoginSettings = await getLoginSettings({ const orgLoginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: orgToCheckForDiscovery, organization: orgToCheckForDiscovery,
}); });
if (orgLoginSettings?.allowDomainDiscovery) { if (orgLoginSettings?.allowDomainDiscovery) {

View File

@@ -64,7 +64,6 @@ export async function setOTP(command: SetOTPCommand) {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: command.organization, organization: command.organization,
}); });

View File

@@ -53,7 +53,6 @@ export async function registerPasskeyLink(
const sessionCookie = await getSessionCookieById({ sessionId }); const sessionCookie = await getSessionCookieById({ sessionId });
const session = await getSession({ const session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });
@@ -74,7 +73,6 @@ export async function registerPasskeyLink(
// use session token to add the passkey // use session token to add the passkey
const registerLink = await createPasskeyRegistrationLink({ const registerLink = await createPasskeyRegistrationLink({
serviceUrl, serviceUrl,
userId, userId,
}); });
@@ -84,7 +82,6 @@ export async function registerPasskeyLink(
return registerPasskey({ return registerPasskey({
serviceUrl, serviceUrl,
userId, userId,
code: registerLink.code, code: registerLink.code,
domain: hostname, domain: hostname,
@@ -112,7 +109,6 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) {
}); });
const session = await getSession({ const session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });
@@ -124,7 +120,6 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) {
return zitadelVerifyPasskeyRegistration({ return zitadelVerifyPasskeyRegistration({
serviceUrl, serviceUrl,
request: create(VerifyPasskeyRegistrationRequestSchema, { request: create(VerifyPasskeyRegistrationRequestSchema, {
passkeyId: command.passkeyId, passkeyId: command.passkeyId,
publicKeyCredential: command.publicKeyCredential, publicKeyCredential: command.publicKeyCredential,
@@ -162,7 +157,6 @@ export async function sendPasskey(command: SendPasskeyCommand) {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -186,7 +180,6 @@ export async function sendPasskey(command: SendPasskeyCommand) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: session?.factors?.user?.id, userId: session?.factors?.user?.id,
}); });

View File

@@ -56,7 +56,6 @@ export async function resetPassword(command: ResetPasswordCommand) {
const users = await listUsers({ const users = await listUsers({
serviceUrl, serviceUrl,
loginName: command.loginName, loginName: command.loginName,
organizationId: command.organization, organizationId: command.organization,
}); });
@@ -106,7 +105,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
if (!sessionCookie) { if (!sessionCookie) {
const users = await listUsers({ const users = await listUsers({
serviceUrl, serviceUrl,
loginName: command.loginName, loginName: command.loginName,
organizationId: command.organization, organizationId: command.organization,
}); });
@@ -121,21 +119,19 @@ export async function sendPassword(command: UpdateSessionCommand) {
loginSettings = await getLoginSettings({ loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: command.organization, organization: command.organization,
}); });
try { try {
session = await createSessionAndUpdateCookie( session = await createSessionAndUpdateCookie({
checks, checks,
command.requestId, requestId: command.requestId,
loginSettings?.passwordCheckLifetime, lifetime: loginSettings?.passwordCheckLifetime,
); });
} catch (error: any) { } catch (error: any) {
if ("failedAttempts" in error && error.failedAttempts) { if ("failedAttempts" in error && error.failedAttempts) {
const lockoutSettings = await getLockoutSettings({ const lockoutSettings = await getLockoutSettings({
serviceUrl, serviceUrl,
orgId: command.organization, orgId: command.organization,
}); });
@@ -167,7 +163,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
if ("failedAttempts" in error && error.failedAttempts) { if ("failedAttempts" in error && error.failedAttempts) {
const lockoutSettings = await getLockoutSettings({ const lockoutSettings = await getLockoutSettings({
serviceUrl, serviceUrl,
orgId: command.organization, orgId: command.organization,
}); });
@@ -189,7 +184,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: session?.factors?.user?.id, userId: session?.factors?.user?.id,
}); });
@@ -203,7 +197,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
if (!loginSettings) { if (!loginSettings) {
loginSettings = await getLoginSettings({ loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: organization:
command.organization ?? session.factors?.user?.organizationId, command.organization ?? session.factors?.user?.organizationId,
}); });
@@ -217,7 +210,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
const expirySettings = await getPasswordExpirySettings({ const expirySettings = await getPasswordExpirySettings({
serviceUrl, serviceUrl,
orgId: command.organization ?? session.factors?.user?.organizationId, orgId: command.organization ?? session.factors?.user?.organizationId,
}); });
@@ -256,7 +248,6 @@ export async function sendPassword(command: UpdateSessionCommand) {
if (command.checks && command.checks.password && session.factors?.user?.id) { if (command.checks && command.checks.password && session.factors?.user?.id) {
const response = await listAuthenticationMethodTypes({ const response = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}); });
if (response.authMethodTypes && response.authMethodTypes.length) { if (response.authMethodTypes && response.authMethodTypes.length) {
@@ -317,7 +308,6 @@ export async function changePassword(command: {
// check for init state // check for init state
const { user } = await getUserByID({ const { user } = await getUserByID({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
}); });
@@ -328,7 +318,6 @@ export async function changePassword(command: {
return setUserPassword({ return setUserPassword({
serviceUrl, serviceUrl,
userId, userId,
password: command.password, password: command.password,
user, user,
@@ -352,7 +341,6 @@ export async function checkSessionAndSetPassword({
const { session } = await getSession({ const { session } = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });
@@ -371,7 +359,6 @@ export async function checkSessionAndSetPassword({
// check if the user has no password set in order to set a password // check if the user has no password set in order to set a password
const authmethods = await listAuthenticationMethodTypes({ const authmethods = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}); });
@@ -392,7 +379,6 @@ export async function checkSessionAndSetPassword({
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: session.factors.user.organizationId, organization: session.factors.user.organizationId,
}); });

View File

@@ -38,7 +38,6 @@ export async function registerUser(command: RegisterUserCommand) {
const addResponse = await addHumanUser({ const addResponse = await addHumanUser({
serviceUrl, serviceUrl,
email: command.email, email: command.email,
firstName: command.firstName, firstName: command.firstName,
lastName: command.lastName, lastName: command.lastName,
@@ -52,7 +51,6 @@ export async function registerUser(command: RegisterUserCommand) {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: command.organization, organization: command.organization,
}); });
@@ -69,11 +67,13 @@ export async function registerUser(command: RegisterUserCommand) {
const checks = create(ChecksSchema, checkPayload); const checks = create(ChecksSchema, checkPayload);
const session = await createSessionAndUpdateCookie( const session = await createSessionAndUpdateCookie({
checks, checks,
command.requestId, requestId: command.requestId,
command.password ? loginSettings?.passwordCheckLifetime : undefined, lifetime: command.password
); ? loginSettings?.passwordCheckLifetime
: undefined,
});
if (!session || !session.factors?.user) { if (!session || !session.factors?.user) {
return { error: "Could not create session" }; return { error: "Could not create session" };
@@ -93,7 +93,6 @@ export async function registerUser(command: RegisterUserCommand) {
} else { } else {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: session?.factors?.user?.id, userId: session?.factors?.user?.id,
}); });

View File

@@ -77,7 +77,6 @@ export async function continueWithSession({
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: session.factors?.user?.organizationId, organization: session.factors?.user?.organizationId,
}); });
@@ -151,7 +150,6 @@ export async function updateSession(options: UpdateSessionCommand) {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization, organization,
}); });
@@ -178,7 +176,6 @@ export async function updateSession(options: UpdateSessionCommand) {
if (checks && checks.password && session.factors?.user?.id) { if (checks && checks.password && session.factors?.user?.id) {
const response = await listAuthenticationMethodTypes({ const response = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: session.factors.user.id, userId: session.factors.user.id,
}); });
if (response.authMethodTypes && response.authMethodTypes.length) { if (response.authMethodTypes && response.authMethodTypes.length) {
@@ -208,7 +205,6 @@ export async function clearSession(options: ClearSessionOptions) {
const deletedSession = await deleteSession({ const deletedSession = await deleteSession({
serviceUrl, serviceUrl,
sessionId: session.id, sessionId: session.id,
sessionToken: session.token, sessionToken: session.token,
}); });
@@ -230,7 +226,6 @@ export async function cleanupSession({ sessionId }: CleanupSessionCommand) {
const deleteResponse = await deleteSession({ const deleteResponse = await deleteSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });

View File

@@ -38,7 +38,6 @@ export async function addU2F(command: RegisterU2FCommand) {
const session = await getSession({ const session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });
@@ -83,7 +82,6 @@ export async function verifyU2F(command: VerifyU2FCommand) {
const session = await getSession({ const session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}); });

View File

@@ -34,7 +34,6 @@ export async function verifyTOTP(
return loadMostRecentSession({ return loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams: { sessionParams: {
loginName, loginName,
organization, organization,
@@ -43,7 +42,6 @@ export async function verifyTOTP(
if (session?.factors?.user?.id) { if (session?.factors?.user?.id) {
return verifyTOTPRegistration({ return verifyTOTPRegistration({
serviceUrl, serviceUrl,
code, code,
userId: session.factors.user.id, userId: session.factors.user.id,
}); });
@@ -69,7 +67,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
const verifyResponse = command.isInvite const verifyResponse = command.isInvite
? await verifyInviteCode({ ? await verifyInviteCode({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
verificationCode: command.code, verificationCode: command.code,
}).catch(() => { }).catch(() => {
@@ -77,7 +74,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
}) })
: await verifyEmail({ : await verifyEmail({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
verificationCode: command.code, verificationCode: command.code,
}).catch(() => { }).catch(() => {
@@ -109,7 +105,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
session = await getSession({ session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}).then((response) => { }).then((response) => {
@@ -124,7 +119,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: session?.factors?.user?.id, userId: session?.factors?.user?.id,
}); });
@@ -136,7 +130,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
} else { } else {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
}); });
@@ -155,7 +148,10 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
}, },
}); });
session = await createSessionAndUpdateCookie(checks, command.requestId); session = await createSessionAndUpdateCookie({
checks,
requestId: command.requestId,
});
} }
if (!session?.factors?.user?.id) { if (!session?.factors?.user?.id) {
@@ -172,13 +168,11 @@ export async function sendVerification(command: VerifyUserByEmailCommand) {
const loginSettings = await getLoginSettings({ const loginSettings = await getLoginSettings({
serviceUrl, serviceUrl,
organization: user.details?.resourceOwner, organization: user.details?.resourceOwner,
}); });
const authMethodResponse = await listAuthenticationMethodTypes({ const authMethodResponse = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: user.userId, userId: user.userId,
}); });
@@ -320,7 +314,6 @@ export async function sendVerificationRedirectWithoutCheck(
session = await getSession({ session = await getSession({
serviceUrl, serviceUrl,
sessionId: sessionCookie.id, sessionId: sessionCookie.id,
sessionToken: sessionCookie.token, sessionToken: sessionCookie.token,
}).then((response) => { }).then((response) => {
@@ -335,7 +328,6 @@ export async function sendVerificationRedirectWithoutCheck(
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: session?.factors?.user?.id, userId: session?.factors?.user?.id,
}); });
@@ -347,7 +339,6 @@ export async function sendVerificationRedirectWithoutCheck(
} else if ("userId" in command) { } else if ("userId" in command) {
const userResponse = await getUserByID({ const userResponse = await getUserByID({
serviceUrl, serviceUrl,
userId: command.userId, userId: command.userId,
}); });
@@ -366,7 +357,10 @@ export async function sendVerificationRedirectWithoutCheck(
}, },
}); });
session = await createSessionAndUpdateCookie(checks, command.requestId); session = await createSessionAndUpdateCookie({
checks,
requestId: command.requestId,
});
} }
if (!session?.factors?.user?.id) { if (!session?.factors?.user?.id) {
@@ -383,7 +377,6 @@ export async function sendVerificationRedirectWithoutCheck(
const authMethodResponse = await listAuthenticationMethodTypes({ const authMethodResponse = await listAuthenticationMethodTypes({
serviceUrl, serviceUrl,
userId: user.userId, userId: user.userId,
}); });

View File

@@ -22,7 +22,6 @@ type LoadMostRecentSessionParams = {
export async function loadMostRecentSession({ export async function loadMostRecentSession({
serviceUrl, serviceUrl,
sessionParams, sessionParams,
}: LoadMostRecentSessionParams): Promise<Session | undefined> { }: LoadMostRecentSessionParams): Promise<Session | undefined> {
const recent = await getMostRecentCookieWithLoginname({ const recent = await getMostRecentCookieWithLoginname({
@@ -32,7 +31,6 @@ export async function loadMostRecentSession({
return getSession({ return getSession({
serviceUrl, serviceUrl,
sessionId: recent.id, sessionId: recent.id,
sessionToken: recent.token, sessionToken: recent.token,
}).then((resp: GetSessionResponse) => resp.session); }).then((resp: GetSessionResponse) => resp.session);

View File

@@ -46,6 +46,7 @@ import {
VerifyU2FRegistrationRequest, VerifyU2FRegistrationRequest,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb"; } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { unstable_cacheLife as cacheLife } from "next/cache"; import { unstable_cacheLife as cacheLife } from "next/cache";
import { getUserAgent } from "./fingerprint";
import { createServiceForHost } from "./service"; import { createServiceForHost } from "./service";
const useCache = process.env.DEBUG !== "true"; const useCache = process.env.DEBUG !== "true";
@@ -246,7 +247,9 @@ export async function createSessionFromChecks({
const sessionService: Client<typeof SessionService> = const sessionService: Client<typeof SessionService> =
await createServiceForHost(SessionService, serviceUrl); await createServiceForHost(SessionService, serviceUrl);
return sessionService.createSession({ checks, lifetime }, {}); const userAgent = await getUserAgent();
return sessionService.createSession({ checks, lifetime, userAgent }, {});
} }
export async function createSessionForUserIdAndIdpIntent({ export async function createSessionForUserIdAndIdpIntent({
@@ -266,6 +269,8 @@ export async function createSessionForUserIdAndIdpIntent({
const sessionService: Client<typeof SessionService> = const sessionService: Client<typeof SessionService> =
await createServiceForHost(SessionService, serviceUrl); await createServiceForHost(SessionService, serviceUrl);
const userAgent = await getUserAgent();
return sessionService.createSession({ return sessionService.createSession({
checks: { checks: {
user: { user: {
@@ -277,6 +282,7 @@ export async function createSessionForUserIdAndIdpIntent({
idpIntent, idpIntent,
}, },
lifetime, lifetime,
userAgent,
}); });
} }
@@ -346,11 +352,7 @@ type ListSessionsCommand = {
ids: string[]; ids: string[];
}; };
export async function listSessions({ export async function listSessions({ serviceUrl, ids }: ListSessionsCommand) {
serviceUrl,
ids,
}: ListSessionsCommand) {
const sessionService: Client<typeof SessionService> = const sessionService: Client<typeof SessionService> =
await createServiceForHost(SessionService, serviceUrl); await createServiceForHost(SessionService, serviceUrl);

21
pnpm-lock.yaml generated
View File

@@ -137,6 +137,9 @@ importers:
tinycolor2: tinycolor2:
specifier: 1.4.2 specifier: 1.4.2
version: 1.4.2 version: 1.4.2
uuid:
specifier: ^11.1.0
version: 11.1.0
devDependencies: devDependencies:
'@bufbuild/buf': '@bufbuild/buf':
specifier: ^1.46.0 specifier: ^1.46.0
@@ -4638,6 +4641,10 @@ packages:
util-deprecate@1.0.2: util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
uuid@11.1.0:
resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
hasBin: true
uuid@8.3.2: uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true hasBin: true
@@ -5477,7 +5484,7 @@ snapshots:
'@formatjs/intl-localematcher@0.5.4': '@formatjs/intl-localematcher@0.5.4':
dependencies: dependencies:
tslib: 2.7.0 tslib: 2.8.1
'@formatjs/intl-localematcher@0.5.8': '@formatjs/intl-localematcher@0.5.8':
dependencies: dependencies:
@@ -5920,7 +5927,7 @@ snapshots:
'@swc/helpers@0.5.13': '@swc/helpers@0.5.13':
dependencies: dependencies:
tslib: 2.7.0 tslib: 2.8.1
'@swc/helpers@0.5.15': '@swc/helpers@0.5.15':
dependencies: dependencies:
@@ -5929,7 +5936,7 @@ snapshots:
'@swc/helpers@0.5.5': '@swc/helpers@0.5.5':
dependencies: dependencies:
'@swc/counter': 0.1.3 '@swc/counter': 0.1.3
tslib: 2.7.0 tslib: 2.8.1
'@tailwindcss/forms@0.5.3(tailwindcss@3.4.14)': '@tailwindcss/forms@0.5.3(tailwindcss@3.4.14)':
dependencies: dependencies:
@@ -7107,7 +7114,7 @@ snapshots:
debug: 4.3.7(supports-color@5.5.0) debug: 4.3.7(supports-color@5.5.0)
enhanced-resolve: 5.17.1 enhanced-resolve: 5.17.1
eslint: 8.57.1 eslint: 8.57.1
eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1))(eslint@8.57.1) eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
fast-glob: 3.3.2 fast-glob: 3.3.2
get-tsconfig: 4.8.0 get-tsconfig: 4.8.0
is-bun-module: 1.1.0 is-bun-module: 1.1.0
@@ -7120,7 +7127,7 @@ snapshots:
- eslint-import-resolver-webpack - eslint-import-resolver-webpack
- supports-color - supports-color
eslint-module-utils@2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1))(eslint@8.57.1): eslint-module-utils@2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
dependencies: dependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@8.1.1)
optionalDependencies: optionalDependencies:
@@ -7141,7 +7148,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 8.57.1 eslint: 8.57.1
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.1))(eslint@8.57.1) eslint-module-utils: 2.8.2(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
hasown: 2.0.2 hasown: 2.0.2
is-core-module: 2.15.1 is-core-module: 2.15.1
is-glob: 4.0.3 is-glob: 4.0.3
@@ -9383,6 +9390,8 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
uuid@11.1.0: {}
uuid@8.3.2: {} uuid@8.3.2: {}
verror@1.10.0: verror@1.10.0: