update nextjs to 15

This commit is contained in:
Max Peintner
2024-11-22 11:25:03 +01:00
parent 19c310f83b
commit 837cd4f674
37 changed files with 775 additions and 547 deletions

View File

@@ -63,9 +63,11 @@ describe("register", () => {
it("should redirect a user who selects passwordless on register to /passkey/set", () => {
cy.visit("/register");
cy.get('input[autocomplete="firstname"]').focus().type("John");
cy.get('input[autocomplete="lastname"]').focus().type("Doe");
cy.get('input[autocomplete="email"]').focus().type("john@zitadel.com");
cy.get('input[data-testid="firstname-text-input"]').focus().type("John");
cy.get('input[data-testid="lastname-text-input"]').focus().type("Doe");
cy.get('input[data-testid="email-text-input"]')
.focus()
.type("john@zitadel.com");
cy.get('input[type="checkbox"][value="privacypolicy"]').check();
cy.get('input[type="checkbox"][value="tos"]').check();
cy.get('button[type="submit"]').click();

View File

@@ -2,7 +2,15 @@
{
"service": "zitadel.settings.v2.SettingsService",
"method": "GetBrandingSettings",
"out": {}
"out": {
"data": {
"settings": {
"darkTheme": {
"backgroundColor": "#ff0000"
}
}
}
}
},
{
"service": "zitadel.settings.v2.SettingsService",
@@ -46,19 +54,5 @@
}
}
}
},
{
"service": "zitadel.settings.v2.SettingsService",
"method": "GetLoginSettings",
"out": {
"data": {
"settings": {
"allowRegister": true,
"passkeysType": 1,
"allowUsernamePassword": true,
"defaultRedirectUri": ""
}
}
}
}
]

View File

@@ -37,6 +37,9 @@ const secureHeaders = [
const nextConfig = {
reactStrictMode: true, // Recommended for the `pages` directory, default in `app`.
swcMinify: true,
experimental: {
dynamicIO: true,
},
images: {
remotePatterns: [
{

View File

@@ -3,7 +3,7 @@
"private": true,
"type": "module",
"scripts": {
"dev": "next dev",
"dev": "next dev --turbopack",
"test": "concurrently --timings --kill-others-on-fail 'npm:test:unit' 'npm:test:integration'",
"test:watch": "concurrently --kill-others 'npm:test:unit:watch' 'npm:test:integration:watch'",
"test:unit": "vitest",
@@ -45,13 +45,13 @@
"copy-to-clipboard": "^3.3.3",
"deepmerge": "^4.3.1",
"moment": "^2.29.4",
"next": "14.2.14",
"next": "15.0.3",
"next-intl": "^3.20.0",
"next-themes": "^0.2.1",
"nice-grpc": "2.0.1",
"qrcode.react": "^3.1.0",
"react": "^18.3.1",
"react-dom": "18.3.1",
"react": "19.0.0-rc-66855b96-20241106",
"react-dom": "19.0.0-rc-66855b96-20241106",
"react-hook-form": "7.39.5",
"swr": "^2.2.0",
"tinycolor2": "1.4.2"
@@ -62,8 +62,8 @@
"@testing-library/react": "^16.0.1",
"@types/ms": "0.7.34",
"@types/node": "22.9.0",
"@types/react": "18.3.12",
"@types/react-dom": "18.3.1",
"@types/react": "npm:types-react@19.0.0-rc.1",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
"@types/tinycolor2": "1.4.3",
"@types/uuid": "^10.0.0",
"@vercel/git-hooks": "1.0.0",
@@ -88,5 +88,11 @@
"ts-proto": "^2.2.7",
"typescript": "^5.6.3",
"zitadel-tailwind-config": "workspace:*"
},
"pnpm": {
"overrides": {
"@types/react": "npm:types-react@19.0.0-rc.1",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1"
}
}
}

View File

@@ -20,11 +20,12 @@ async function loadSessions() {
}
}
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "accounts" });

View File

@@ -15,11 +15,12 @@ import {
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "authenticator" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -12,13 +12,13 @@ const PROVIDER_NAME_MAPPING: {
[IdentityProviderType.AZURE_AD]: "Microsoft",
};
export default async function Page({
searchParams,
params,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
params: { provider: string };
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
params: Promise<{ provider: string }>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "idp" });

View File

@@ -29,13 +29,14 @@ async function loginFailed(branding?: BrandingSettings) {
</DynamicTheme>
);
}
export default async function Page({
searchParams,
params,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
params: { provider: string };
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
params: Promise<{ provider: string }>;
}
) {
const params = await props.params;
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "idp" });
const { id, token, authRequestId, organization } = searchParams;
@@ -137,12 +138,12 @@ export default async function Page({
if (idpLink) {
return (
// TODO: possibily login user now
<DynamicTheme branding={branding}>
(<DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4">
<h1>{t("linkingSuccess.title")}</h1>
<div>{t("linkingSuccess.description")}</div>
</div>
</DynamicTheme>
</DynamicTheme>)
);
}
}

View File

@@ -12,11 +12,12 @@ function getIdentityProviders(orgId?: string) {
});
}
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "idp" });

View File

@@ -9,11 +9,12 @@ import {
} from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "invite" });

View File

@@ -7,11 +7,12 @@ import { HumanUser, User } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { getLocale, getTranslations } from "next-intl/server";
import Link from "next/link";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "invite" });

View File

@@ -19,11 +19,12 @@ function getIdentityProviders(orgId?: string) {
});
}
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "loginname" });

View File

@@ -12,11 +12,12 @@ import {
} from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "mfa" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -32,11 +32,12 @@ function isSessionValid(session: Partial<Session>): {
return { valid, verifiedAt };
}
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "mfa" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -6,13 +6,14 @@ import { loadMostRecentSession } from "@/lib/session";
import { getBrandingSettings, getLoginSettings } from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
params,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
params: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
params: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const params = await props.params;
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "otp" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -17,13 +17,14 @@ import { getLocale, getTranslations } from "next-intl/server";
import Link from "next/link";
import { redirect } from "next/navigation";
export default async function Page({
searchParams,
params,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
params: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
params: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const params = await props.params;
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "otp" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -11,11 +11,12 @@ import {
} from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "passkey" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -6,11 +6,12 @@ import { loadMostRecentSession } from "@/lib/session";
import { getBrandingSettings } from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "passkey" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -10,11 +10,12 @@ import {
} from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "password" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -12,11 +12,12 @@ import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import { PasskeysType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "password" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -13,11 +13,12 @@ import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { HumanUser, User } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "password" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -10,11 +10,12 @@ import {
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "register" });
@@ -39,8 +40,11 @@ export default async function Page({
if (!loginSettings?.allowRegister) {
return (
<DynamicTheme branding={branding}>
<div>{t("disabled.title")}</div>
<p className="ztdl-p">{t("disabled.description")}</p>
<div className="flex flex-col items-center space-y-4">
<h1>{t("disabled.title")}</h1>
<p className="ztdl-p">{t("disabled.description")}</p>
{JSON.stringify(loginSettings)}
</div>
</DynamicTheme>
);
}

View File

@@ -10,11 +10,12 @@ import {
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "register" });
@@ -40,8 +41,10 @@ export default async function Page({
return missingData ? (
<DynamicTheme branding={branding}>
<div>{t("missingdata.title")}</div>
<p className="ztdl-p">{t("missingdata.description")}</p>
<div className="flex flex-col items-center space-y-4">
<h1>{t("missingdata.title")}</h1>
<p className="ztdl-p">{t("missingdata.description")}</p>
</div>
</DynamicTheme>
) : loginSettings?.allowRegister && loginSettings.allowUsernamePassword ? (
<DynamicTheme branding={branding}>
@@ -63,8 +66,10 @@ export default async function Page({
</DynamicTheme>
) : (
<DynamicTheme branding={branding}>
<div>{t("disabled.title")}</div>
<p className="ztdl-p">{t("disabled.description")}</p>
<div className="flex flex-col items-center space-y-4">
<h1>{t("disabled.title")}</h1>
<p className="ztdl-p">{t("disabled.description")}</p>
</div>
</DynamicTheme>
);
}

View File

@@ -46,7 +46,8 @@ async function loadSession(loginName: string, authRequestId?: string) {
);
}
export default async function Page({ searchParams }: { searchParams: any }) {
export default async function Page(props: { searchParams: Promise<any> }) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "signedin" });

View File

@@ -7,11 +7,12 @@ import { loadMostRecentSession } from "@/lib/session";
import { getBrandingSettings, getSession } from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "u2f" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -6,11 +6,12 @@ import { loadMostRecentSession } from "@/lib/session";
import { getBrandingSettings } from "@/lib/zitadel";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
export default async function Page(
props: {
searchParams: Promise<Record<string | number | symbol, string | undefined>>;
}
) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "u2f" });
const tError = await getTranslations({ locale, namespace: "error" });

View File

@@ -12,7 +12,8 @@ import { HumanUser, User } from "@zitadel/proto/zitadel/user/v2/user_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { getLocale, getTranslations } from "next-intl/server";
export default async function Page({ searchParams }: { searchParams: any }) {
export default async function Page(props: { searchParams: Promise<any> }) {
const searchParams = await props.searchParams;
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "verify" });
const tError = await getTranslations({ locale, namespace: "error" });
@@ -60,7 +61,7 @@ export default async function Page({ searchParams }: { searchParams: any }) {
}
return (
<DynamicTheme branding={branding}>
(<DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4">
<h1>{t("verify.title")}</h1>
<p className="ztdl-p mb-6 block">{t("verify.description")}</p>
@@ -92,14 +93,14 @@ export default async function Page({ searchParams }: { searchParams: any }) {
/>
) : (
// check if auth methods are set
<VerifyForm
(<VerifyForm
userId={userId}
code={code}
isInvite={invite === "true"}
params={params}
/>
/>)
)}
</div>
</DynamicTheme>
</DynamicTheme>)
);
}

View File

@@ -50,6 +50,7 @@ export function RegisterForm({
loginSettings,
}: Props) {
const t = useTranslations("register");
console.log(loginSettings);
const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur",

View File

@@ -5,7 +5,7 @@ import { cookies } from "next/headers";
export default getRequestConfig(async () => {
const fallback = "en";
const cookiesList = cookies();
const cookiesList = await cookies();
const locale: string = cookiesList.get(LANGUAGE_COOKIE_NAME)?.value ?? "en";
const userMessages = (await import(`../../locales/${locale}.json`)).default;

View File

@@ -1,7 +1,7 @@
"use server";
import { timestampDate, timestampFromMs } from "@zitadel/client";
import { cookies } from "next/headers";
import { cookies, type UnsafeUnwrappedCookies } from "next/headers";
import { LANGUAGE_COOKIE_NAME } from "./i18n";
// TODO: improve this to handle overflow
@@ -21,7 +21,7 @@ export type Cookie = {
type SessionCookie<T> = Cookie & T;
function setSessionHttpOnlyCookie<T>(sessions: SessionCookie<T>[]) {
const cookiesList = cookies();
const cookiesList = (cookies() as unknown as UnsafeUnwrappedCookies);
return cookiesList.set({
name: "sessions",
@@ -32,7 +32,7 @@ function setSessionHttpOnlyCookie<T>(sessions: SessionCookie<T>[]) {
}
export async function setLanguageCookie(language: string) {
const cookiesList = cookies();
const cookiesList = await cookies();
await cookiesList.set({
name: LANGUAGE_COOKIE_NAME,
@@ -46,7 +46,7 @@ export async function addSessionToCookie<T>(
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
let currentSessions: SessionCookie<T>[] = stringifiedCookie?.value
@@ -90,7 +90,7 @@ export async function updateSessionCookie<T>(
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
const sessions: SessionCookie<T>[] = stringifiedCookie?.value
@@ -121,7 +121,7 @@ export async function removeSessionFromCookie<T>(
session: SessionCookie<T>,
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
const sessions: SessionCookie<T>[] = stringifiedCookie?.value
@@ -143,7 +143,7 @@ export async function removeSessionFromCookie<T>(
}
export async function getMostRecentSessionCookie<T>(): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
@@ -166,7 +166,7 @@ export async function getSessionCookieById<T>({
sessionId: string;
organization?: string;
}): Promise<SessionCookie<T>> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
@@ -194,7 +194,7 @@ export async function getSessionCookieByLoginName<T>({
loginName?: string;
organization?: string;
}): Promise<SessionCookie<T>> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
@@ -222,7 +222,7 @@ export async function getSessionCookieByLoginName<T>({
export async function getAllSessionCookieIds<T>(
cleanup: boolean = false,
): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
@@ -253,7 +253,7 @@ export async function getAllSessionCookieIds<T>(
export async function getAllSessions<T>(
cleanup: boolean = false,
): Promise<SessionCookie<T>[]> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {
@@ -287,7 +287,7 @@ export async function getMostRecentCookieWithLoginname<T>({
loginName?: string;
organization?: string;
}): Promise<any> {
const cookiesList = cookies();
const cookiesList = await cookies();
const stringifiedCookie = cookiesList.get("sessions");
if (stringifiedCookie?.value) {

View File

@@ -20,7 +20,7 @@ export type RegisterUserResponse = {
};
export async function inviteUser(command: InviteUserCommand) {
const host = headers().get("host");
const host = (await headers()).get("host");
const human = await addHumanUser({
email: command.email,

View File

@@ -44,7 +44,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
});
if (identityProviders.length === 1) {
const host = headers().get("host");
const host = (await headers()).get("host");
const identityProviderType = identityProviders[0].type;
const provider = idpTypeToSlug(identityProviderType);
@@ -81,7 +81,7 @@ export async function sendLoginname(command: SendLoginnameCommand) {
});
if (identityProviders.length === 1) {
const host = headers().get("host");
const host = (await headers()).get("host");
const identityProviderId = identityProviders[0].idpId;
const idp = await getIDPByID(identityProviderId);

View File

@@ -37,7 +37,7 @@ export async function registerPasskeyLink(
sessionToken: sessionCookie.token,
});
const host = headers().get("host");
const host = (await headers()).get("host");
if (!host) {
throw new Error("Could not get domain");
@@ -73,7 +73,7 @@ export async function verifyPasskey(command: VerifyPasskeyCommand) {
// if no name is provided, try to generate one from the user agent
let passkeyName = command.passkeyName;
if (!!!passkeyName) {
const headersList = headers();
const headersList = await headers();
const userAgentStructure = { headers: headersList };
const { browser, device, os } = userAgent(userAgentStructure);

View File

@@ -30,7 +30,7 @@ type ResetPasswordCommand = {
};
export async function resetPassword(command: ResetPasswordCommand) {
const host = headers().get("host");
const host = (await headers()).get("host");
const users = await listUsers({
loginName: command.loginName,

View File

@@ -32,7 +32,7 @@ export async function addU2F(command: RegisterU2FCommand) {
sessionToken: sessionCookie.token,
});
const domain = headers().get("host");
const domain = (await headers()).get("host");
if (!domain) {
return { error: "Could not get domain" };
@@ -54,7 +54,7 @@ export async function addU2F(command: RegisterU2FCommand) {
export async function verifyU2F(command: VerifyU2FCommand) {
let passkeyName = command.passkeyName;
if (!!!passkeyName) {
const headersList = headers();
const headersList = await headers();
const userAgentStructure = { headers: headersList };
const { browser, device, os } = userAgent(userAgentStructure);

View File

@@ -18,17 +18,11 @@ import {
VerifyU2FRegistrationRequest,
} from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { create, fromJson, toJson } from "@zitadel/client";
import { create } from "@zitadel/client";
import { TextQueryMethod } from "@zitadel/proto/zitadel/object/v2/object_pb";
import { CreateCallbackRequest } from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
import { Organization } from "@zitadel/proto/zitadel/org/v2/org_pb";
import { BrandingSettingsSchema } from "@zitadel/proto/zitadel/settings/v2/branding_settings_pb";
import { LegalAndSupportSettingsSchema } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb";
import {
IdentityProviderType,
LoginSettingsSchema,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { PasswordComplexitySettingsSchema } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
import { IdentityProviderType } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import type { RedirectURLsJson } from "@zitadel/proto/zitadel/user/v2/idp_pb";
import {
NotificationType,
@@ -43,7 +37,7 @@ import {
User,
UserState,
} from "@zitadel/proto/zitadel/user/v2/user_pb";
import { unstable_cache } from "next/cache";
import { unstable_cacheLife as cacheLife } from "next/cache";
import { PROVIDER_MAPPING } from "./idp";
const SESSION_LIFETIME_S = 3600; // TODO load from oidc settings
@@ -66,43 +60,19 @@ export const orgService = createOrganizationServiceClient(transport);
export const settingsService = createSettingsServiceClient(transport);
export async function getBrandingSettings(organization?: string) {
return unstable_cache(
async () => {
return await settingsService
.getBrandingSettings({ ctx: makeReqCtx(organization) }, {})
.then((resp) =>
resp.settings
? toJson(BrandingSettingsSchema, resp.settings)
: undefined,
);
},
["brandingSettings", organization ?? "default"],
{
revalidate: CACHE_REVALIDATION_INTERVAL_IN_SECONDS,
tags: ["brandingSettings"],
},
)().then((resp) =>
resp ? fromJson(BrandingSettingsSchema, resp) : undefined,
);
"use cache";
cacheLife("hours");
return settingsService
.getBrandingSettings({ ctx: makeReqCtx(organization) }, {})
.then((resp) => (resp.settings ? resp.settings : undefined));
}
export async function getLoginSettings(orgId?: string) {
return unstable_cache(
async () => {
return await settingsService
.getLoginSettings({ ctx: makeReqCtx(orgId) }, {})
.then((resp) =>
resp.settings
? toJson(LoginSettingsSchema, resp.settings)
: undefined,
);
},
["loginSettings", orgId ?? "default"],
{
revalidate: CACHE_REVALIDATION_INTERVAL_IN_SECONDS,
tags: ["loginSettings"],
},
)().then((resp) => (resp ? fromJson(LoginSettingsSchema, resp) : undefined));
"use cache";
return await settingsService
.getLoginSettings({ ctx: makeReqCtx(orgId) }, {})
.then((resp) => (resp.settings ? resp.settings : undefined));
}
export async function listIDPLinks(userId: string) {
@@ -132,51 +102,24 @@ export async function registerTOTP(userId: string) {
}
export async function getGeneralSettings() {
"use cache";
return settingsService
.getGeneralSettings({}, {})
.then((resp) => resp.supportedLanguages);
}
export async function getLegalAndSupportSettings(organization?: string) {
return unstable_cache(
async () => {
return await settingsService
.getLegalAndSupportSettings({ ctx: makeReqCtx(organization) }, {})
.then((resp) =>
resp.settings
? toJson(LegalAndSupportSettingsSchema, resp.settings)
: undefined,
);
},
["legalAndSupportSettings", organization ?? "default"],
{
revalidate: CACHE_REVALIDATION_INTERVAL_IN_SECONDS,
tags: ["legalAndSupportSettings"],
},
)().then((resp) =>
resp ? fromJson(LegalAndSupportSettingsSchema, resp) : undefined,
);
"use cache";
return settingsService
.getLegalAndSupportSettings({ ctx: makeReqCtx(organization) }, {})
.then((resp) => (resp.settings ? resp.settings : undefined));
}
export async function getPasswordComplexitySettings(organization?: string) {
return unstable_cache(
async () => {
return await settingsService
.getPasswordComplexitySettings({ ctx: makeReqCtx(organization) })
.then((resp) =>
resp.settings
? toJson(PasswordComplexitySettingsSchema, resp.settings)
: undefined,
);
},
["complexitySettings", organization ?? "default"],
{
revalidate: CACHE_REVALIDATION_INTERVAL_IN_SECONDS,
tags: ["complexitySettings"],
},
)().then((resp) =>
resp ? fromJson(PasswordComplexitySettingsSchema, resp) : undefined,
);
"use cache";
return settingsService
.getPasswordComplexitySettings({ ctx: makeReqCtx(organization) })
.then((resp) => (resp.settings ? resp.settings : undefined));
}
export async function createSessionFromChecks(

842
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff