mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 11:17:32 +00:00
move flow completion to signedin page
This commit is contained in:
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "Willkommen {user}!",
|
||||
"description": "Sie sind angemeldet.",
|
||||
"continue": "Weiter"
|
||||
"continue": "Weiter",
|
||||
"error": {
|
||||
"title": "Fehler",
|
||||
"description": "Ein Fehler ist aufgetreten."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "Keine Benutzer-ID angegeben!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "Welcome {user}!",
|
||||
"description": "You are signed in.",
|
||||
"continue": "Continue"
|
||||
"continue": "Continue",
|
||||
"error": {
|
||||
"title": "Error",
|
||||
"description": "An error occurred while trying to sign in."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "No userId provided!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "¡Bienvenido {user}!",
|
||||
"description": "Has iniciado sesión.",
|
||||
"continue": "Continuar"
|
||||
"continue": "Continuar",
|
||||
"error": {
|
||||
"title": "Error",
|
||||
"description": "Ocurrió un error al iniciar sesión."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "¡No se proporcionó userId!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "Benvenuto {user}!",
|
||||
"description": "Sei connesso.",
|
||||
"continue": "Continua"
|
||||
"continue": "Continua",
|
||||
"error": {
|
||||
"title": "Errore",
|
||||
"description": "Si è verificato un errore durante il tentativo di accesso."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "Nessun userId fornito!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "Witaj {user}!",
|
||||
"description": "Jesteś zalogowany.",
|
||||
"continue": "Kontynuuj"
|
||||
"continue": "Kontynuuj",
|
||||
"error": {
|
||||
"title": "Błąd",
|
||||
"description": "Nie można załadować danych. Sprawdź połączenie z internetem lub spróbuj ponownie później."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "Nie podano identyfikatora użytkownika!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "Добро пожаловать, {user}!",
|
||||
"description": "Вы вошли в систему.",
|
||||
"continue": "Продолжить"
|
||||
"continue": "Продолжить",
|
||||
"error": {
|
||||
"title": "Ошибка",
|
||||
"description": "Не удалось войти в систему. Проверьте свои данные и попробуйте снова."
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "Не указан userId!",
|
||||
|
@@ -166,7 +166,11 @@
|
||||
"signedin": {
|
||||
"title": "欢迎 {user}!",
|
||||
"description": "您已登录。",
|
||||
"continue": "继续"
|
||||
"continue": "继续",
|
||||
"error": {
|
||||
"title": "错误",
|
||||
"description": "登录时发生错误。"
|
||||
}
|
||||
},
|
||||
"verify": {
|
||||
"userIdMissing": "未提供用户 ID!",
|
||||
|
@@ -2,7 +2,11 @@ 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 { getSessionCookieById } from "@/lib/cookies";
|
||||
import {
|
||||
getMostRecentCookieWithLoginname,
|
||||
getSessionCookieById,
|
||||
} from "@/lib/cookies";
|
||||
import { completeDeviceAuthorization } from "@/lib/server/device";
|
||||
import { getServiceUrlFromHeaders } from "@/lib/service";
|
||||
import { loadMostRecentSession } from "@/lib/session";
|
||||
import {
|
||||
@@ -41,6 +45,36 @@ export default async function Page(props: { searchParams: Promise<any> }) {
|
||||
|
||||
const { loginName, requestId, organization, sessionId } = searchParams;
|
||||
|
||||
const branding = await getBrandingSettings({
|
||||
serviceUrl,
|
||||
organization,
|
||||
});
|
||||
|
||||
// complete device authorization flow if device requestId is present
|
||||
if (requestId && requestId.startsWith("device_")) {
|
||||
const cookie = sessionId
|
||||
? await getSessionCookieById({ sessionId, organization })
|
||||
: await getMostRecentCookieWithLoginname({
|
||||
loginName: loginName,
|
||||
organization: organization,
|
||||
});
|
||||
|
||||
await completeDeviceAuthorization(requestId.replace("device_", ""), {
|
||||
sessionId: cookie.id,
|
||||
sessionToken: cookie.token,
|
||||
}).catch((err) => {
|
||||
return (
|
||||
<DynamicTheme branding={branding}>
|
||||
<div className="flex flex-col items-center space-y-4">
|
||||
<h1>{t("error.title")}</h1>
|
||||
<p className="ztdl-p mb-6 block">{t("error.description")}</p>
|
||||
<Alert>{err.message}</Alert>
|
||||
</div>
|
||||
</DynamicTheme>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const sessionFactors = sessionId
|
||||
? await loadSessionById(serviceUrl, sessionId, organization)
|
||||
: await loadMostRecentSession({
|
||||
@@ -48,11 +82,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
|
||||
sessionParams: { loginName, organization },
|
||||
});
|
||||
|
||||
const branding = await getBrandingSettings({
|
||||
serviceUrl,
|
||||
organization,
|
||||
});
|
||||
|
||||
let loginSettings;
|
||||
if (!requestId) {
|
||||
loginSettings = await getLoginSettings({
|
||||
@@ -69,6 +98,13 @@ export default async function Page(props: { searchParams: Promise<any> }) {
|
||||
</h1>
|
||||
<p className="ztdl-p mb-6 block">{t("description")}</p>
|
||||
|
||||
<UserAvatar
|
||||
loginName={loginName ?? sessionFactors?.factors?.user?.loginName}
|
||||
displayName={sessionFactors?.factors?.user?.displayName}
|
||||
showDropdown={!(requestId && requestId.startsWith("device_"))}
|
||||
searchParams={searchParams}
|
||||
/>
|
||||
|
||||
{requestId && requestId.startsWith("device_") && (
|
||||
<Alert type={AlertType.INFO}>
|
||||
You can now close this window and return to the device where you
|
||||
@@ -76,13 +112,6 @@ export default async function Page(props: { searchParams: Promise<any> }) {
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<UserAvatar
|
||||
loginName={loginName ?? sessionFactors?.factors?.user?.loginName}
|
||||
displayName={sessionFactors?.factors?.user?.displayName}
|
||||
showDropdown
|
||||
searchParams={searchParams}
|
||||
/>
|
||||
|
||||
{/* {sessionFactors?.id && (
|
||||
<SelfServiceMenu sessionId={sessionFactors?.id} />
|
||||
)} */}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { denyDeviceAuthorization } from "@/lib/server/oidc";
|
||||
import { completeDeviceAuthorization } from "@/lib/server/device";
|
||||
import { useTranslations } from "next-intl";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
@@ -27,7 +27,9 @@ export function ConsentScreen({
|
||||
|
||||
async function denyDeviceAuth() {
|
||||
setLoading(true);
|
||||
const response = await denyDeviceAuthorization(deviceAuthorizationRequestId)
|
||||
const response = await completeDeviceAuthorization(
|
||||
deviceAuthorizationRequestId,
|
||||
)
|
||||
.catch(() => {
|
||||
setError("Could not register user");
|
||||
return;
|
||||
|
@@ -36,7 +36,7 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
|
||||
|
||||
const response = await getDeviceAuthorizationRequest(value.userCode)
|
||||
.catch(() => {
|
||||
setError("Could not complete the request");
|
||||
setError("Could not continue the request");
|
||||
return;
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -44,7 +44,7 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
|
||||
});
|
||||
|
||||
if (!response || !response.deviceAuthorizationRequest?.id) {
|
||||
setError("Could not complete the request");
|
||||
setError("Could not continue the request");
|
||||
return;
|
||||
}
|
||||
|
||||
|
20
apps/login/src/lib/server/device.ts
Normal file
20
apps/login/src/lib/server/device.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
"use server";
|
||||
|
||||
import { authorizeOrDenyDeviceAuthorization } from "@/lib/zitadel";
|
||||
import { headers } from "next/headers";
|
||||
import { getServiceUrlFromHeaders } from "../service";
|
||||
|
||||
export async function completeDeviceAuthorization(
|
||||
deviceAuthorizationId: string,
|
||||
session?: { sessionId: string; sessionToken: string },
|
||||
) {
|
||||
const _headers = await headers();
|
||||
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
|
||||
|
||||
// without the session, device auth request is denied
|
||||
return authorizeOrDenyDeviceAuthorization({
|
||||
serviceUrl,
|
||||
deviceAuthorizationId,
|
||||
session,
|
||||
});
|
||||
}
|
@@ -1,9 +1,6 @@
|
||||
"use server";
|
||||
|
||||
import {
|
||||
authorizeOrDenyDeviceAuthorization,
|
||||
getDeviceAuthorizationRequest as zitadelGetDeviceAuthorizationRequest,
|
||||
} from "@/lib/zitadel";
|
||||
import { getDeviceAuthorizationRequest as zitadelGetDeviceAuthorizationRequest } from "@/lib/zitadel";
|
||||
import { headers } from "next/headers";
|
||||
import { getServiceUrlFromHeaders } from "../service";
|
||||
|
||||
@@ -16,14 +13,3 @@ export async function getDeviceAuthorizationRequest(userCode: string) {
|
||||
userCode,
|
||||
});
|
||||
}
|
||||
|
||||
export async function denyDeviceAuthorization(deviceAuthorizationId: string) {
|
||||
const _headers = await headers();
|
||||
const { serviceUrl } = getServiceUrlFromHeaders(_headers);
|
||||
|
||||
// without the session, device auth request is denied
|
||||
return authorizeOrDenyDeviceAuthorization({
|
||||
serviceUrl,
|
||||
deviceAuthorizationId,
|
||||
});
|
||||
}
|
||||
|
@@ -952,6 +952,10 @@ export async function authorizeOrDenyDeviceAuthorization({
|
||||
deviceAuthorizationId: string;
|
||||
session?: { sessionId: string; sessionToken: string };
|
||||
}) {
|
||||
console.log("authorizeOrDenyDeviceAuthorization");
|
||||
|
||||
console.log("session", session);
|
||||
|
||||
const oidcService = await createServiceForHost(OIDCService, serviceUrl);
|
||||
|
||||
return oidcService.authorizeOrDenyDeviceAuthorization({
|
||||
|
Reference in New Issue
Block a user