This commit is contained in:
Max Peintner
2025-05-06 14:41:44 +02:00
parent 6e20bd3beb
commit a4e08b5419
11 changed files with 23 additions and 92 deletions

View File

@@ -200,6 +200,7 @@
"deny": "Ablehnen"
},
"scope": {
"openid": "Überprüfen Sie Ihre Identität.",
"email": "Zugriff auf Ihre E-Mail-Adresse.",
"profile": "Zugriff auf Ihre vollständigen Profilinformationen.",
"offline_access": "Erlauben Sie den Offline-Zugriff auf Ihr Konto."

View File

@@ -190,7 +190,7 @@
"device": {
"usercode": {
"title": "Device code",
"description": "Enter the code.",
"description": "Enter the code displayed on your app or device.",
"submit": "Continue"
},
"request": {
@@ -200,8 +200,9 @@
"deny": "Deny"
},
"scope": {
"email": "Access your email address.",
"profile": "Access your full profile information.",
"openid": "Verify your identity.",
"email": "Access to your email address.",
"profile": "Access to your full profile information.",
"offline_access": "Allow offline access to your account."
}
},

View File

@@ -200,6 +200,7 @@
"deny": "Denegar"
},
"scope": {
"openid": "Verifica tu identidad.",
"email": "Accede a tu dirección de correo electrónico.",
"profile": "Accede a la información completa de tu perfil.",
"offline_access": "Permitir acceso sin conexión a tu cuenta."

View File

@@ -200,6 +200,7 @@
"deny": "Nega"
},
"scope": {
"openid": "Verifica la tua identità.",
"email": "Accedi al tuo indirizzo email.",
"profile": "Accedi alle informazioni complete del tuo profilo.",
"offline_access": "Consenti l'accesso offline al tuo account."

View File

@@ -200,6 +200,7 @@
"deny": "Odmów"
},
"scope": {
"openid": "Zweryfikuj swoją tożsamość.",
"email": "Uzyskaj dostęp do swojego adresu e-mail.",
"profile": "Uzyskaj dostęp do pełnych informacji o swoim profilu.",
"offline_access": "Zezwól na dostęp offline do swojego konta."

View File

@@ -200,6 +200,7 @@
"deny": "Запретить"
},
"scope": {
"openid": "Проверка вашей личности.",
"email": "Доступ к вашему адресу электронной почты.",
"profile": "Доступ к полной информации вашего профиля.",
"offline_access": "Разрешить офлайн-доступ к вашему аккаунту."

View File

@@ -200,6 +200,7 @@
"deny": "拒绝"
},
"scope": {
"openid": "验证您的身份。",
"email": "访问您的电子邮件地址。",
"profile": "访问您的完整个人资料信息。",
"offline_access": "允许离线访问您的账户。"

View File

@@ -63,10 +63,7 @@ export default async function Page(props: {
}
return (
<DynamicTheme
branding={branding}
appName={deviceAuthorizationRequest?.appName}
>
<DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4">
<h1>
{t("request.title", { appName: deviceAuthorizationRequest?.appName })}

View File

@@ -2,95 +2,17 @@ import { Alert, AlertType } from "@/components/alert";
import { Button, ButtonVariants } from "@/components/button";
import { DynamicTheme } from "@/components/dynamic-theme";
import { UserAvatar } from "@/components/user-avatar";
import {
getMostRecentCookieWithLoginname,
getSessionCookieById,
} from "@/lib/cookies";
import { getSessionCookieById } from "@/lib/cookies";
import { getServiceUrlFromHeaders } from "@/lib/service";
import { loadMostRecentSession } from "@/lib/session";
import {
authorizeOrDenyDeviceAuthorization,
createCallback,
createResponse,
getBrandingSettings,
getLoginSettings,
getSession,
} from "@/lib/zitadel";
import { create } from "@zitadel/client";
import {
CreateCallbackRequestSchema,
SessionSchema,
} from "@zitadel/proto/zitadel/oidc/v2/oidc_service_pb";
import { CreateResponseRequestSchema } from "@zitadel/proto/zitadel/saml/v2/saml_service_pb";
import { getLocale, getTranslations } from "next-intl/server";
import { headers } from "next/headers";
import Link from "next/link";
import { redirect } from "next/navigation";
async function loadSession(
serviceUrl: string,
loginName: string,
requestId?: string,
) {
const recent = await getMostRecentCookieWithLoginname({ loginName });
if (requestId && requestId.startsWith("oidc_")) {
return createCallback({
serviceUrl,
req: create(CreateCallbackRequestSchema, {
authRequestId: requestId,
callbackKind: {
case: "session",
value: create(SessionSchema, {
sessionId: recent.id,
sessionToken: recent.token,
}),
},
}),
}).then(({ callbackUrl }) => {
return redirect(callbackUrl);
});
} else if (requestId && requestId.startsWith("saml_")) {
return createResponse({
serviceUrl,
req: create(CreateResponseRequestSchema, {
samlRequestId: requestId.replace("saml_", ""),
responseKind: {
case: "session",
value: {
sessionId: recent.id,
sessionToken: recent.token,
},
},
}),
}).then(({ url }) => {
return redirect(url);
});
} else if (requestId && requestId.startsWith("device_")) {
const session = {
sessionId: recent.id,
sessionToken: recent.token,
};
return authorizeOrDenyDeviceAuthorization({
serviceUrl,
deviceAuthorizationId: requestId.replace("device_", ""),
session,
}).then(() => {
return session;
});
}
return getSession({
serviceUrl,
sessionId: recent.id,
sessionToken: recent.token,
}).then((response) => {
if (response?.session) {
return response.session;
}
});
}
async function loadSessionById(
serviceUrl: string,

View File

@@ -1,3 +1,5 @@
"use client";
import { denyDeviceAuthorization } from "@/lib/server/oidc";
import { useTranslations } from "next-intl";
import Link from "next/link";
@@ -32,11 +34,9 @@ export function ConsentScreen({
setLoading(false);
});
if (response && "redirect" in response && response.redirect) {
if (response) {
return router.push("/device");
}
return response;
}
return (
@@ -77,7 +77,7 @@ export function ConsentScreen({
onClick={() => {
denyDeviceAuth();
}}
variant={ButtonVariants.Destructive}
variant={ButtonVariants.Secondary}
data-testid="deny-button"
>
{loading && <Spinner className="h-5 w-5 mr-2" />}

View File

@@ -7,8 +7,8 @@ type FinishFlowCommand =
function goToSignedInPage(
props:
| { sessionId: string; organization?: string }
| { organization?: string; loginName: string },
| { sessionId: string; organization?: string; requestId?: string }
| { organization?: string; loginName: string; requestId?: string },
) {
const params = new URLSearchParams({});
@@ -24,6 +24,11 @@ function goToSignedInPage(
params.append("organization", props.organization);
}
// required to show conditional UI for device flow
if (props.requestId) {
params.append("requestId", props.requestId);
}
return `/signedin?` + params;
}