diff --git a/apps/login/package.json b/apps/login/package.json index 9411bc6c69..c200079530 100644 --- a/apps/login/package.json +++ b/apps/login/package.json @@ -56,7 +56,8 @@ "react-dom": "19.0.0", "react-hook-form": "7.39.5", "swr": "^2.2.0", - "tinycolor2": "1.4.2" + "tinycolor2": "1.4.2", + "uuid": "^11.1.0" }, "devDependencies": { "@bufbuild/buf": "^1.46.0", diff --git a/apps/login/src/app/(login)/accounts/page.tsx b/apps/login/src/app/(login)/accounts/page.tsx index 1823310e97..6a57f05cee 100644 --- a/apps/login/src/app/(login)/accounts/page.tsx +++ b/apps/login/src/app/(login)/accounts/page.tsx @@ -19,7 +19,6 @@ async function loadSessions({ serviceUrl }: { serviceUrl: string }) { if (ids && ids.length) { const response = await listSessions({ serviceUrl, - ids: ids.filter((id) => !!id) as string[], }); return response?.sessions ?? []; @@ -56,7 +55,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization: organization ?? defaultOrganization, }); diff --git a/apps/login/src/app/(login)/authenticator/set/page.tsx b/apps/login/src/app/(login)/authenticator/set/page.tsx index 19bf0883e1..793cb6714d 100644 --- a/apps/login/src/app/(login)/authenticator/set/page.tsx +++ b/apps/login/src/app/(login)/authenticator/set/page.tsx @@ -49,7 +49,6 @@ export default async function Page(props: { return listAuthenticationMethodTypes({ serviceUrl, - userId, }).then((methods) => { return getUserByID({ serviceUrl, userId }).then((user) => { @@ -74,7 +73,6 @@ export default async function Page(props: { ) { return loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -92,15 +90,10 @@ export default async function Page(props: { const recent = await getSessionCookieById({ sessionId, organization }); return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((sessionResponse) => { - return getAuthMethodsAndUser( - serviceUrl, - - sessionResponse.session, - ); + return getAuthMethodsAndUser(serviceUrl, sessionResponse.session); }); } @@ -110,19 +103,16 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization: sessionWithData.factors?.user?.organizationId, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization: sessionWithData.factors?.user?.organizationId, }); const identityProviders = await getActiveIdentityProviders({ serviceUrl, - orgId: sessionWithData.factors?.user?.organizationId, linking_allowed: true, }).then((resp) => { diff --git a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx index 9490b62bf2..82c7224a92 100644 --- a/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx @@ -29,13 +29,11 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); @@ -54,7 +52,6 @@ export default async function Page(props: { if (userId) { const userResponse = await getUserByID({ serviceUrl, - userId, }); if (userResponse) { @@ -70,7 +67,6 @@ export default async function Page(props: { const authMethodsResponse = await listAuthenticationMethodTypes({ serviceUrl, - userId, }); if (authMethodsResponse.authMethodTypes) { diff --git a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx index 4ef0b50933..4b6b873c30 100644 --- a/apps/login/src/app/(login)/idp/[provider]/success/page.tsx +++ b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx @@ -44,7 +44,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); @@ -54,7 +53,6 @@ export default async function Page(props: { const intent = await retrieveIDPIntent({ serviceUrl, - id, token, }); @@ -79,7 +77,6 @@ export default async function Page(props: { const idp = await getIDPByID({ serviceUrl, - id: idpInformation.idpId, }); const options = idp?.config?.options; @@ -100,7 +97,6 @@ export default async function Page(props: { try { idpLink = await addIDPLink({ serviceUrl, - idp: { id: idpInformation.idpId, userId: idpInformation.userId, @@ -145,7 +141,6 @@ export default async function Page(props: { } else { foundUser = await listUsers({ serviceUrl, - userName: idpInformation.userName, email, }).then((response) => { @@ -158,7 +153,6 @@ export default async function Page(props: { try { idpLink = await addIDPLink({ serviceUrl, - idp: { id: idpInformation.idpId, 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 const orgs = await getOrgsByDomain({ serviceUrl, - domain: suffix, }); const orgToCheckForDiscovery = @@ -209,7 +202,6 @@ export default async function Page(props: { const orgLoginSettings = await getLoginSettings({ serviceUrl, - organization: orgToCheckForDiscovery, }); if (orgLoginSettings?.allowDomainDiscovery) { @@ -230,7 +222,6 @@ export default async function Page(props: { const newUser = await addHuman({ serviceUrl, - request: userData, }); diff --git a/apps/login/src/app/(login)/idp/page.tsx b/apps/login/src/app/(login)/idp/page.tsx index 67b3ac1cf7..e8c63512d2 100644 --- a/apps/login/src/app/(login)/idp/page.tsx +++ b/apps/login/src/app/(login)/idp/page.tsx @@ -20,7 +20,6 @@ export default async function Page(props: { const identityProviders = await getActiveIdentityProviders({ serviceUrl, - orgId: organization, }).then((resp) => { return resp.identityProviders; @@ -28,7 +27,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/invite/page.tsx b/apps/login/src/app/(login)/invite/page.tsx index 1efe8b98a8..ed29624d0e 100644 --- a/apps/login/src/app/(login)/invite/page.tsx +++ b/apps/login/src/app/(login)/invite/page.tsx @@ -34,19 +34,16 @@ export default async function Page(props: { const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); const passwordComplexitySettings = await getPasswordComplexitySettings({ serviceUrl, - organization, }); const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/invite/success/page.tsx b/apps/login/src/app/(login)/invite/success/page.tsx index b38735aa30..8a2cfb96e9 100644 --- a/apps/login/src/app/(login)/invite/success/page.tsx +++ b/apps/login/src/app/(login)/invite/success/page.tsx @@ -32,7 +32,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); @@ -41,7 +40,6 @@ export default async function Page(props: { if (userId) { const userResponse = await getUserByID({ serviceUrl, - userId, }); if (userResponse) { diff --git a/apps/login/src/app/(login)/loginname/page.tsx b/apps/login/src/app/(login)/loginname/page.tsx index 85327c7a85..e3406b5fee 100644 --- a/apps/login/src/app/(login)/loginname/page.tsx +++ b/apps/login/src/app/(login)/loginname/page.tsx @@ -40,19 +40,16 @@ export default async function Page(props: { const loginSettings = await getLoginSettings({ serviceUrl, - organization: organization ?? defaultOrganization, }); const contextLoginSettings = await getLoginSettings({ serviceUrl, - organization, }); const identityProviders = await getActiveIdentityProviders({ serviceUrl, - orgId: organization ?? defaultOrganization, }).then((resp) => { return resp.identityProviders; @@ -60,7 +57,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization: organization ?? defaultOrganization, }); diff --git a/apps/login/src/app/(login)/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx index 47853a2b3f..2838457b30 100644 --- a/apps/login/src/app/(login)/mfa/page.tsx +++ b/apps/login/src/app/(login)/mfa/page.tsx @@ -38,7 +38,6 @@ export default async function Page(props: { ) { return loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -47,7 +46,6 @@ export default async function Page(props: { if (session && session.factors?.user?.id) { return listAuthenticationMethodTypes({ serviceUrl, - userId: session.factors.user.id, }).then((methods) => { return { @@ -67,14 +65,12 @@ export default async function Page(props: { const recent = await getSessionCookieById({ sessionId, organization }); return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((response) => { if (response?.session && response.session.factors?.user?.id) { return listAuthenticationMethodTypes({ serviceUrl, - userId: response.session.factors.user.id, }).then((methods) => { return { @@ -88,7 +84,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/mfa/set/page.tsx b/apps/login/src/app/(login)/mfa/set/page.tsx index 498b063428..19251b060b 100644 --- a/apps/login/src/app/(login)/mfa/set/page.tsx +++ b/apps/login/src/app/(login)/mfa/set/page.tsx @@ -61,7 +61,6 @@ export default async function Page(props: { return listAuthenticationMethodTypes({ serviceUrl, - userId, }).then((methods) => { return getUserByID({ serviceUrl, userId }).then((user) => { @@ -85,7 +84,6 @@ export default async function Page(props: { ) { return loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -108,12 +106,10 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization: sessionWithData.factors?.user?.organizationId, }); diff --git a/apps/login/src/app/(login)/otp/[method]/page.tsx b/apps/login/src/app/(login)/otp/[method]/page.tsx index 51881e1bf7..f566f2b0e6 100644 --- a/apps/login/src/app/(login)/otp/[method]/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/page.tsx @@ -47,7 +47,6 @@ export default async function Page(props: { ? await loadSessionById(serviceUrl, sessionId, organization) : await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization }, }); @@ -59,7 +58,6 @@ export default async function Page(props: { const recent = await getSessionCookieById({ sessionId, organization }); return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).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 const branding = await getBrandingSettings({ serviceUrl, - organization: organization ?? session?.factors?.user?.organizationId, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization: organization ?? session?.factors?.user?.organizationId, }); diff --git a/apps/login/src/app/(login)/otp/[method]/set/page.tsx b/apps/login/src/app/(login)/otp/[method]/set/page.tsx index 5d994a5833..b16dd177a9 100644 --- a/apps/login/src/app/(login)/otp/[method]/set/page.tsx +++ b/apps/login/src/app/(login)/otp/[method]/set/page.tsx @@ -38,18 +38,15 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); const session = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -61,7 +58,6 @@ export default async function Page(props: { if (method === "time-based") { await registerTOTP({ serviceUrl, - userId: session.factors.user.id, }) .then((resp) => { @@ -76,7 +72,6 @@ export default async function Page(props: { // does not work await addOTPSMS({ serviceUrl, - userId: session.factors.user.id, }).catch((error) => { error = new Error("Could not add OTP via SMS"); @@ -85,7 +80,6 @@ export default async function Page(props: { // works await addOTPEmail({ serviceUrl, - userId: session.factors.user.id, }).catch((error) => { error = new Error("Could not add OTP via Email"); diff --git a/apps/login/src/app/(login)/passkey/page.tsx b/apps/login/src/app/(login)/passkey/page.tsx index 6496039bed..cef7032a54 100644 --- a/apps/login/src/app/(login)/passkey/page.tsx +++ b/apps/login/src/app/(login)/passkey/page.tsx @@ -27,7 +27,6 @@ export default async function Page(props: { ? await loadSessionById(serviceUrl, sessionId, organization) : await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization }, }); @@ -39,7 +38,6 @@ export default async function Page(props: { const recent = await getSessionCookieById({ sessionId, organization }); return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((response) => { @@ -51,7 +49,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/passkey/set/page.tsx b/apps/login/src/app/(login)/passkey/set/page.tsx index 64e3cf2a8e..b9745bdd68 100644 --- a/apps/login/src/app/(login)/passkey/set/page.tsx +++ b/apps/login/src/app/(login)/passkey/set/page.tsx @@ -23,7 +23,6 @@ export default async function Page(props: { const session = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -32,7 +31,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/password/change/page.tsx b/apps/login/src/app/(login)/password/change/page.tsx index af55c524e4..f0ab94d315 100644 --- a/apps/login/src/app/(login)/password/change/page.tsx +++ b/apps/login/src/app/(login)/password/change/page.tsx @@ -28,7 +28,6 @@ export default async function Page(props: { // also allow no session to be found (ignoreUnkownUsername) const sessionFactors = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -37,19 +36,16 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); const passwordComplexity = await getPasswordComplexitySettings({ serviceUrl, - organization: sessionFactors?.factors?.user?.organizationId, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization: sessionFactors?.factors?.user?.organizationId, }); diff --git a/apps/login/src/app/(login)/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx index e1190911b2..64f2709009 100644 --- a/apps/login/src/app/(login)/password/page.tsx +++ b/apps/login/src/app/(login)/password/page.tsx @@ -43,7 +43,6 @@ export default async function Page(props: { try { sessionFactors = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -56,12 +55,10 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization: organization ?? defaultOrganization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization: organization ?? defaultOrganization, }); diff --git a/apps/login/src/app/(login)/password/set/page.tsx b/apps/login/src/app/(login)/password/set/page.tsx index 4c9407c82d..2205f5e0a5 100644 --- a/apps/login/src/app/(login)/password/set/page.tsx +++ b/apps/login/src/app/(login)/password/set/page.tsx @@ -34,7 +34,6 @@ export default async function Page(props: { if (loginName) { session = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -44,19 +43,16 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); const passwordComplexity = await getPasswordComplexitySettings({ serviceUrl, - organization: session?.factors?.user?.organizationId, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); @@ -65,7 +61,6 @@ export default async function Page(props: { if (userId) { const userResponse = await getUserByID({ serviceUrl, - userId, }); user = userResponse.user; diff --git a/apps/login/src/app/(login)/register/page.tsx b/apps/login/src/app/(login)/register/page.tsx index a9dc15b75c..7a69755f4d 100644 --- a/apps/login/src/app/(login)/register/page.tsx +++ b/apps/login/src/app/(login)/register/page.tsx @@ -35,24 +35,20 @@ export default async function Page(props: { const legal = await getLegalAndSupportSettings({ serviceUrl, - organization, }); const passwordComplexitySettings = await getPasswordComplexitySettings({ serviceUrl, - organization, }); const branding = await getBrandingSettings({ serviceUrl, - organization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/register/password/page.tsx b/apps/login/src/app/(login)/register/password/page.tsx index 20a76363e6..8a2c0e1649 100644 --- a/apps/login/src/app/(login)/register/password/page.tsx +++ b/apps/login/src/app/(login)/register/password/page.tsx @@ -37,24 +37,20 @@ export default async function Page(props: { const legal = await getLegalAndSupportSettings({ serviceUrl, - organization, }); const passwordComplexitySettings = await getPasswordComplexitySettings({ serviceUrl, - organization, }); const branding = await getBrandingSettings({ serviceUrl, - organization, }); const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/signedin/page.tsx b/apps/login/src/app/(login)/signedin/page.tsx index c6b747befa..8c5c5486ac 100644 --- a/apps/login/src/app/(login)/signedin/page.tsx +++ b/apps/login/src/app/(login)/signedin/page.tsx @@ -33,7 +33,6 @@ async function loadSession( if (requestId && requestId.startsWith("oidc_")) { return createCallback({ serviceUrl, - req: create(CreateCallbackRequestSchema, { authRequestId: requestId, callbackKind: { @@ -67,7 +66,6 @@ async function loadSession( return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((response) => { @@ -86,16 +84,10 @@ export default async function Page(props: { searchParams: Promise }) { const { serviceUrl } = getServiceUrlFromHeaders(_headers); const { loginName, requestId, organization } = searchParams; - const sessionFactors = await loadSession( - serviceUrl, - - loginName, - requestId, - ); + const sessionFactors = await loadSession(serviceUrl, loginName, requestId); const branding = await getBrandingSettings({ serviceUrl, - organization, }); @@ -103,7 +95,6 @@ export default async function Page(props: { searchParams: Promise }) { if (!requestId) { loginSettings = await getLoginSettings({ serviceUrl, - organization, }); } diff --git a/apps/login/src/app/(login)/u2f/page.tsx b/apps/login/src/app/(login)/u2f/page.tsx index 139f0f1a50..bf8bd7ce37 100644 --- a/apps/login/src/app/(login)/u2f/page.tsx +++ b/apps/login/src/app/(login)/u2f/page.tsx @@ -29,7 +29,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); @@ -37,7 +36,6 @@ export default async function Page(props: { ? await loadSessionById(serviceUrl, sessionId, organization) : await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization }, }); @@ -49,7 +47,6 @@ export default async function Page(props: { const recent = await getSessionCookieById({ sessionId, organization }); return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((response) => { diff --git a/apps/login/src/app/(login)/u2f/set/page.tsx b/apps/login/src/app/(login)/u2f/set/page.tsx index fa8d6d57d6..0119502ffd 100644 --- a/apps/login/src/app/(login)/u2f/set/page.tsx +++ b/apps/login/src/app/(login)/u2f/set/page.tsx @@ -23,7 +23,6 @@ export default async function Page(props: { const sessionFactors = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -32,7 +31,6 @@ export default async function Page(props: { const branding = await getBrandingSettings({ serviceUrl, - organization, }); diff --git a/apps/login/src/app/(login)/verify/page.tsx b/apps/login/src/app/(login)/verify/page.tsx index e9d2029cbd..1464d5185a 100644 --- a/apps/login/src/app/(login)/verify/page.tsx +++ b/apps/login/src/app/(login)/verify/page.tsx @@ -35,7 +35,6 @@ export default async function Page(props: { searchParams: Promise }) { const branding = await getBrandingSettings({ serviceUrl, - organization, }); @@ -51,7 +50,6 @@ export default async function Page(props: { searchParams: Promise }) { if ("loginName" in searchParams) { sessionFactors = await loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -86,7 +84,6 @@ export default async function Page(props: { searchParams: Promise }) { const userResponse = await getUserByID({ serviceUrl, - userId, }); if (userResponse) { diff --git a/apps/login/src/app/login/route.ts b/apps/login/src/app/login/route.ts index 2db81e070e..7a0c147865 100644 --- a/apps/login/src/app/login/route.ts +++ b/apps/login/src/app/login/route.ts @@ -159,7 +159,6 @@ export async function GET(request: NextRequest) { if (orgDomain) { const orgs = await getOrgsByDomain({ serviceUrl, - domain: orgDomain, }); if (orgs.result && orgs.result.length === 1) { @@ -367,7 +366,6 @@ export async function GET(request: NextRequest) { try { const { callbackUrl } = await createCallback({ serviceUrl, - req: create(CreateCallbackRequestSchema, { authRequestId: requestId.replace("oidc_", ""), callbackKind: { diff --git a/apps/login/src/lib/fingerprint.ts b/apps/login/src/lib/fingerprint.ts new file mode 100644 index 0000000000..55b59dadc8 --- /dev/null +++ b/apps/login/src/lib/fingerprint.ts @@ -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 { + const cookie = await getFingerprintIdCookie(); + if (cookie) { + return cookie.value; + } + + const fingerprintId = await getFingerprintId(); + await setFingerprintIdCookie(fingerprintId); + return fingerprintId; +} + +export async function getUserAgent(): Promise { + 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; +} diff --git a/apps/login/src/lib/self.ts b/apps/login/src/lib/self.ts index a68ba38180..d1971c19b1 100644 --- a/apps/login/src/lib/self.ts +++ b/apps/login/src/lib/self.ts @@ -32,7 +32,6 @@ export async function setMyPassword({ const { session } = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); diff --git a/apps/login/src/lib/server/cookie.ts b/apps/login/src/lib/server/cookie.ts index c5d9ced252..d54a4047b1 100644 --- a/apps/login/src/lib/server/cookie.ts +++ b/apps/login/src/lib/server/cookie.ts @@ -46,24 +46,23 @@ const passwordAttemptsHandler = (error: ConnectError) => { throw error; }; -export async function createSessionAndUpdateCookie( - checks: Checks, - requestId: string | undefined, - lifetime?: Duration, -): Promise { +export async function createSessionAndUpdateCookie(command: { + checks: Checks; + requestId: string | undefined; + lifetime?: Duration; +}): Promise { const _headers = await headers(); const { serviceUrl } = getServiceUrlFromHeaders(_headers); const createdSession = await createSessionFromChecks({ serviceUrl, - checks, - lifetime, + checks: command.checks, + lifetime: command.lifetime, }); if (createdSession) { return getSession({ serviceUrl, - sessionId: createdSession.sessionId, sessionToken: createdSession.sessionToken, }).then((response) => { @@ -83,8 +82,8 @@ export async function createSessionAndUpdateCookie( loginName: response.session.factors.user.loginName ?? "", }; - if (requestId) { - sessionCookie.requestId = requestId; + if (command.requestId) { + sessionCookie.requestId = command.requestId; } if (response.session.factors.user.organizationId) { @@ -118,7 +117,6 @@ export async function createSessionForIdpAndUpdateCookie( const createdSession = await createSessionForUserIdAndIdpIntent({ serviceUrl, - userId, idpIntent, lifetime, @@ -139,7 +137,6 @@ export async function createSessionForIdpAndUpdateCookie( const { session } = await getSession({ serviceUrl, - sessionId: createdSession.sessionId, sessionToken: createdSession.sessionToken, }); @@ -191,7 +188,6 @@ export async function setSessionAndUpdateCookie( return setSession({ serviceUrl, - sessionId: recentCookie.id, sessionToken: recentCookie.token, challenges, @@ -219,7 +215,6 @@ export async function setSessionAndUpdateCookie( return getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }).then((response) => { diff --git a/apps/login/src/lib/server/idp.ts b/apps/login/src/lib/server/idp.ts index 33d7d26bac..aa38a63f27 100644 --- a/apps/login/src/lib/server/idp.ts +++ b/apps/login/src/lib/server/idp.ts @@ -62,6 +62,7 @@ export async function createNewSessionFromIdpIntent( command: CreateNewSessionCommand, ) { const _headers = await headers(); + const { serviceUrl } = getServiceUrlFromHeaders(_headers); const host = _headers.get("host"); @@ -75,7 +76,6 @@ export async function createNewSessionFromIdpIntent( const userResponse = await getUserByID({ serviceUrl, - userId: command.userId, }); @@ -85,7 +85,6 @@ export async function createNewSessionFromIdpIntent( const loginSettings = await getLoginSettings({ serviceUrl, - organization: userResponse.user.details?.resourceOwner, }); diff --git a/apps/login/src/lib/server/invite.ts b/apps/login/src/lib/server/invite.ts index c54362889a..9821336099 100644 --- a/apps/login/src/lib/server/invite.ts +++ b/apps/login/src/lib/server/invite.ts @@ -31,7 +31,6 @@ export async function inviteUser(command: InviteUserCommand) { const human = await addHumanUser({ serviceUrl, - email: command.email, firstName: command.firstName, lastName: command.lastName, diff --git a/apps/login/src/lib/server/loginname.ts b/apps/login/src/lib/server/loginname.ts index 1739528dc2..78aa455483 100644 --- a/apps/login/src/lib/server/loginname.ts +++ b/apps/login/src/lib/server/loginname.ts @@ -43,7 +43,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const loginSettingsByContext = await getLoginSettings({ serviceUrl, - organization: command.organization, }); @@ -53,7 +52,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { let searchUsersRequest: SearchUsersCommand = { serviceUrl, - searchValue: command.loginName, organizationId: command.organization, loginSettings: loginSettingsByContext, @@ -75,7 +73,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const redirectUserToSingleIDPIfAvailable = async () => { const identityProviders = await getActiveIdentityProviders({ serviceUrl, - orgId: command.organization, }).then((resp) => { return resp.identityProviders; @@ -128,7 +125,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const redirectUserToIDP = async (userId: string) => { const identityProviders = await listIDPLinks({ serviceUrl, - userId, }).then((resp) => { return resp.result; @@ -147,7 +143,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const idp = await getIDPByID({ serviceUrl, - id: identityProviderId, }); @@ -199,7 +194,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const userLoginSettings = await getLoginSettings({ serviceUrl, - organization: user.details?.resourceOwner, }); @@ -241,10 +235,10 @@ export async function sendLoginname(command: SendLoginnameCommand) { user: { search: { case: "userId", value: userId } }, }); - const session = await createSessionAndUpdateCookie( + const session = await createSessionAndUpdateCookie({ checks, - command.requestId, - ); + requestId: command.requestId, + }); if (!session.factors?.user?.id) { return { error: "Could not create session for user" }; @@ -257,7 +251,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const methods = await listAuthenticationMethodTypes({ serviceUrl, - 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 const orgs = await getOrgsByDomain({ serviceUrl, - domain: suffix, }); const orgToCheckForDiscovery = @@ -424,7 +416,6 @@ export async function sendLoginname(command: SendLoginnameCommand) { const orgLoginSettings = await getLoginSettings({ serviceUrl, - organization: orgToCheckForDiscovery, }); if (orgLoginSettings?.allowDomainDiscovery) { diff --git a/apps/login/src/lib/server/otp.ts b/apps/login/src/lib/server/otp.ts index 11cf050bfd..77def53af6 100644 --- a/apps/login/src/lib/server/otp.ts +++ b/apps/login/src/lib/server/otp.ts @@ -64,7 +64,6 @@ export async function setOTP(command: SetOTPCommand) { const loginSettings = await getLoginSettings({ serviceUrl, - organization: command.organization, }); diff --git a/apps/login/src/lib/server/passkeys.ts b/apps/login/src/lib/server/passkeys.ts index 7febf5b3ce..bbed8e9175 100644 --- a/apps/login/src/lib/server/passkeys.ts +++ b/apps/login/src/lib/server/passkeys.ts @@ -53,7 +53,6 @@ export async function registerPasskeyLink( const sessionCookie = await getSessionCookieById({ sessionId }); const session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); @@ -74,7 +73,6 @@ export async function registerPasskeyLink( // use session token to add the passkey const registerLink = await createPasskeyRegistrationLink({ serviceUrl, - userId, }); @@ -84,7 +82,6 @@ export async function registerPasskeyLink( return registerPasskey({ serviceUrl, - userId, code: registerLink.code, domain: hostname, @@ -112,7 +109,6 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) { }); const session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); @@ -124,7 +120,6 @@ export async function verifyPasskeyRegistration(command: VerifyPasskeyCommand) { return zitadelVerifyPasskeyRegistration({ serviceUrl, - request: create(VerifyPasskeyRegistrationRequestSchema, { passkeyId: command.passkeyId, publicKeyCredential: command.publicKeyCredential, @@ -162,7 +157,6 @@ export async function sendPasskey(command: SendPasskeyCommand) { const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); @@ -186,7 +180,6 @@ export async function sendPasskey(command: SendPasskeyCommand) { const userResponse = await getUserByID({ serviceUrl, - userId: session?.factors?.user?.id, }); diff --git a/apps/login/src/lib/server/password.ts b/apps/login/src/lib/server/password.ts index 92f3337af4..3fff193851 100644 --- a/apps/login/src/lib/server/password.ts +++ b/apps/login/src/lib/server/password.ts @@ -56,7 +56,6 @@ export async function resetPassword(command: ResetPasswordCommand) { const users = await listUsers({ serviceUrl, - loginName: command.loginName, organizationId: command.organization, }); @@ -106,7 +105,6 @@ export async function sendPassword(command: UpdateSessionCommand) { if (!sessionCookie) { const users = await listUsers({ serviceUrl, - loginName: command.loginName, organizationId: command.organization, }); @@ -121,21 +119,19 @@ export async function sendPassword(command: UpdateSessionCommand) { loginSettings = await getLoginSettings({ serviceUrl, - organization: command.organization, }); try { - session = await createSessionAndUpdateCookie( + session = await createSessionAndUpdateCookie({ checks, - command.requestId, - loginSettings?.passwordCheckLifetime, - ); + requestId: command.requestId, + lifetime: loginSettings?.passwordCheckLifetime, + }); } catch (error: any) { if ("failedAttempts" in error && error.failedAttempts) { const lockoutSettings = await getLockoutSettings({ serviceUrl, - orgId: command.organization, }); @@ -167,7 +163,6 @@ export async function sendPassword(command: UpdateSessionCommand) { if ("failedAttempts" in error && error.failedAttempts) { const lockoutSettings = await getLockoutSettings({ serviceUrl, - orgId: command.organization, }); @@ -189,7 +184,6 @@ export async function sendPassword(command: UpdateSessionCommand) { const userResponse = await getUserByID({ serviceUrl, - userId: session?.factors?.user?.id, }); @@ -203,7 +197,6 @@ export async function sendPassword(command: UpdateSessionCommand) { if (!loginSettings) { loginSettings = await getLoginSettings({ serviceUrl, - organization: command.organization ?? session.factors?.user?.organizationId, }); @@ -217,7 +210,6 @@ export async function sendPassword(command: UpdateSessionCommand) { const expirySettings = await getPasswordExpirySettings({ serviceUrl, - 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) { const response = await listAuthenticationMethodTypes({ serviceUrl, - userId: session.factors.user.id, }); if (response.authMethodTypes && response.authMethodTypes.length) { @@ -317,7 +308,6 @@ export async function changePassword(command: { // check for init state const { user } = await getUserByID({ serviceUrl, - userId: command.userId, }); @@ -328,7 +318,6 @@ export async function changePassword(command: { return setUserPassword({ serviceUrl, - userId, password: command.password, user, @@ -352,7 +341,6 @@ export async function checkSessionAndSetPassword({ const { session } = await getSession({ serviceUrl, - sessionId: sessionCookie.id, 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 const authmethods = await listAuthenticationMethodTypes({ serviceUrl, - userId: session.factors.user.id, }); @@ -392,7 +379,6 @@ export async function checkSessionAndSetPassword({ const loginSettings = await getLoginSettings({ serviceUrl, - organization: session.factors.user.organizationId, }); diff --git a/apps/login/src/lib/server/register.ts b/apps/login/src/lib/server/register.ts index 36103e9bf9..59f6d00171 100644 --- a/apps/login/src/lib/server/register.ts +++ b/apps/login/src/lib/server/register.ts @@ -38,7 +38,6 @@ export async function registerUser(command: RegisterUserCommand) { const addResponse = await addHumanUser({ serviceUrl, - email: command.email, firstName: command.firstName, lastName: command.lastName, @@ -52,7 +51,6 @@ export async function registerUser(command: RegisterUserCommand) { const loginSettings = await getLoginSettings({ serviceUrl, - organization: command.organization, }); @@ -69,11 +67,13 @@ export async function registerUser(command: RegisterUserCommand) { const checks = create(ChecksSchema, checkPayload); - const session = await createSessionAndUpdateCookie( + const session = await createSessionAndUpdateCookie({ checks, - command.requestId, - command.password ? loginSettings?.passwordCheckLifetime : undefined, - ); + requestId: command.requestId, + lifetime: command.password + ? loginSettings?.passwordCheckLifetime + : undefined, + }); if (!session || !session.factors?.user) { return { error: "Could not create session" }; @@ -93,7 +93,6 @@ export async function registerUser(command: RegisterUserCommand) { } else { const userResponse = await getUserByID({ serviceUrl, - userId: session?.factors?.user?.id, }); diff --git a/apps/login/src/lib/server/session.ts b/apps/login/src/lib/server/session.ts index 6a1aa5af9b..66688bf415 100644 --- a/apps/login/src/lib/server/session.ts +++ b/apps/login/src/lib/server/session.ts @@ -77,7 +77,6 @@ export async function continueWithSession({ const loginSettings = await getLoginSettings({ serviceUrl, - organization: session.factors?.user?.organizationId, }); @@ -151,7 +150,6 @@ export async function updateSession(options: UpdateSessionCommand) { const loginSettings = await getLoginSettings({ serviceUrl, - organization, }); @@ -178,7 +176,6 @@ export async function updateSession(options: UpdateSessionCommand) { if (checks && checks.password && session.factors?.user?.id) { const response = await listAuthenticationMethodTypes({ serviceUrl, - userId: session.factors.user.id, }); if (response.authMethodTypes && response.authMethodTypes.length) { @@ -208,7 +205,6 @@ export async function clearSession(options: ClearSessionOptions) { const deletedSession = await deleteSession({ serviceUrl, - sessionId: session.id, sessionToken: session.token, }); @@ -230,7 +226,6 @@ export async function cleanupSession({ sessionId }: CleanupSessionCommand) { const deleteResponse = await deleteSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); diff --git a/apps/login/src/lib/server/u2f.ts b/apps/login/src/lib/server/u2f.ts index a011a16c11..a13be1176a 100644 --- a/apps/login/src/lib/server/u2f.ts +++ b/apps/login/src/lib/server/u2f.ts @@ -38,7 +38,6 @@ export async function addU2F(command: RegisterU2FCommand) { const session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); @@ -83,7 +82,6 @@ export async function verifyU2F(command: VerifyU2FCommand) { const session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }); diff --git a/apps/login/src/lib/server/verify.ts b/apps/login/src/lib/server/verify.ts index 765fda4b78..513aa03d40 100644 --- a/apps/login/src/lib/server/verify.ts +++ b/apps/login/src/lib/server/verify.ts @@ -34,7 +34,6 @@ export async function verifyTOTP( return loadMostRecentSession({ serviceUrl, - sessionParams: { loginName, organization, @@ -43,7 +42,6 @@ export async function verifyTOTP( if (session?.factors?.user?.id) { return verifyTOTPRegistration({ serviceUrl, - code, userId: session.factors.user.id, }); @@ -69,7 +67,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { const verifyResponse = command.isInvite ? await verifyInviteCode({ serviceUrl, - userId: command.userId, verificationCode: command.code, }).catch(() => { @@ -77,7 +74,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { }) : await verifyEmail({ serviceUrl, - userId: command.userId, verificationCode: command.code, }).catch(() => { @@ -109,7 +105,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }).then((response) => { @@ -124,7 +119,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { const userResponse = await getUserByID({ serviceUrl, - userId: session?.factors?.user?.id, }); @@ -136,7 +130,6 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { } else { const userResponse = await getUserByID({ serviceUrl, - 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) { @@ -172,13 +168,11 @@ export async function sendVerification(command: VerifyUserByEmailCommand) { const loginSettings = await getLoginSettings({ serviceUrl, - organization: user.details?.resourceOwner, }); const authMethodResponse = await listAuthenticationMethodTypes({ serviceUrl, - userId: user.userId, }); @@ -320,7 +314,6 @@ export async function sendVerificationRedirectWithoutCheck( session = await getSession({ serviceUrl, - sessionId: sessionCookie.id, sessionToken: sessionCookie.token, }).then((response) => { @@ -335,7 +328,6 @@ export async function sendVerificationRedirectWithoutCheck( const userResponse = await getUserByID({ serviceUrl, - userId: session?.factors?.user?.id, }); @@ -347,7 +339,6 @@ export async function sendVerificationRedirectWithoutCheck( } else if ("userId" in command) { const userResponse = await getUserByID({ serviceUrl, - 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) { @@ -383,7 +377,6 @@ export async function sendVerificationRedirectWithoutCheck( const authMethodResponse = await listAuthenticationMethodTypes({ serviceUrl, - userId: user.userId, }); diff --git a/apps/login/src/lib/session.ts b/apps/login/src/lib/session.ts index f9eb0ceeb2..9698c4c4ba 100644 --- a/apps/login/src/lib/session.ts +++ b/apps/login/src/lib/session.ts @@ -22,7 +22,6 @@ type LoadMostRecentSessionParams = { export async function loadMostRecentSession({ serviceUrl, - sessionParams, }: LoadMostRecentSessionParams): Promise { const recent = await getMostRecentCookieWithLoginname({ @@ -32,7 +31,6 @@ export async function loadMostRecentSession({ return getSession({ serviceUrl, - sessionId: recent.id, sessionToken: recent.token, }).then((resp: GetSessionResponse) => resp.session); diff --git a/apps/login/src/lib/zitadel.ts b/apps/login/src/lib/zitadel.ts index 5e3fdec323..89f587d800 100644 --- a/apps/login/src/lib/zitadel.ts +++ b/apps/login/src/lib/zitadel.ts @@ -46,6 +46,7 @@ import { VerifyU2FRegistrationRequest, } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { unstable_cacheLife as cacheLife } from "next/cache"; +import { getUserAgent } from "./fingerprint"; import { createServiceForHost } from "./service"; const useCache = process.env.DEBUG !== "true"; @@ -246,7 +247,9 @@ export async function createSessionFromChecks({ const sessionService: Client = await createServiceForHost(SessionService, serviceUrl); - return sessionService.createSession({ checks, lifetime }, {}); + const userAgent = await getUserAgent(); + + return sessionService.createSession({ checks, lifetime, userAgent }, {}); } export async function createSessionForUserIdAndIdpIntent({ @@ -266,6 +269,8 @@ export async function createSessionForUserIdAndIdpIntent({ const sessionService: Client = await createServiceForHost(SessionService, serviceUrl); + const userAgent = await getUserAgent(); + return sessionService.createSession({ checks: { user: { @@ -277,6 +282,7 @@ export async function createSessionForUserIdAndIdpIntent({ idpIntent, }, lifetime, + userAgent, }); } @@ -346,11 +352,7 @@ type ListSessionsCommand = { ids: string[]; }; -export async function listSessions({ - serviceUrl, - - ids, -}: ListSessionsCommand) { +export async function listSessions({ serviceUrl, ids }: ListSessionsCommand) { const sessionService: Client = await createServiceForHost(SessionService, serviceUrl); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e7902b1bd..b28520f9e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,6 +137,9 @@ importers: tinycolor2: specifier: 1.4.2 version: 1.4.2 + uuid: + specifier: ^11.1.0 + version: 11.1.0 devDependencies: '@bufbuild/buf': specifier: ^1.46.0 @@ -4638,6 +4641,10 @@ packages: util-deprecate@1.0.2: 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: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -5477,7 +5484,7 @@ snapshots: '@formatjs/intl-localematcher@0.5.4': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 '@formatjs/intl-localematcher@0.5.8': dependencies: @@ -5920,7 +5927,7 @@ snapshots: '@swc/helpers@0.5.13': dependencies: - tslib: 2.7.0 + tslib: 2.8.1 '@swc/helpers@0.5.15': dependencies: @@ -5929,7 +5936,7 @@ snapshots: '@swc/helpers@0.5.5': dependencies: '@swc/counter': 0.1.3 - tslib: 2.7.0 + tslib: 2.8.1 '@tailwindcss/forms@0.5.3(tailwindcss@3.4.14)': dependencies: @@ -7107,7 +7114,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.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 get-tsconfig: 4.8.0 is-bun-module: 1.1.0 @@ -7120,7 +7127,7 @@ snapshots: - eslint-import-resolver-webpack - 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: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: @@ -7141,7 +7148,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 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 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -9383,6 +9390,8 @@ snapshots: util-deprecate@1.0.2: {} + uuid@11.1.0: {} + uuid@8.3.2: {} verror@1.10.0: