feat: add frontend

This commit is contained in:
Stavros
2026-06-11 18:40:56 +03:00
parent 24f166551e
commit cd51263428
8 changed files with 71 additions and 35 deletions
+2
View File
@@ -6,6 +6,7 @@ type ScreenParams = {
oidc_ticket?: string;
oidc_scope?: string;
oidc_name?: string;
oidc_show_consent?: boolean;
};
const zodScreenParams = z.object({
@@ -14,6 +15,7 @@ const zodScreenParams = z.object({
oidc_ticket: z.string().optional(),
oidc_scope: z.string().optional(),
oidc_name: z.string().optional(),
oidc_show_consent: z.stringbool().optional(),
});
export function useScreenParams(params: URLSearchParams): ScreenParams {
+58 -24
View File
@@ -25,6 +25,7 @@ import {
recompileScreenParams,
useScreenParams,
} from "@/lib/hooks/screen-params";
import { useEffect } from "react";
type Scope = {
id: string;
@@ -90,25 +91,48 @@ export const AuthorizePage = () => {
const isOidc = screenParams.login_for === "oidc";
const compiledParams = recompileScreenParams(screenParams);
const authorizeMutation = useMutation({
mutationFn: () => {
return axios.post("/api/oidc/authorize-complete", {
ticket: screenParams.oidc_ticket,
});
},
mutationKey: ["authorize", screenParams.oidc_ticket],
onSuccess: (data) => {
toast.info(t("authorizeSuccessTitle"), {
description: t("authorizeSuccessSubtitle"),
});
window.location.replace(data.data.redirect_uri);
},
onError: (error) => {
window.location.replace(
`/error?error=${encodeURIComponent(error.message)}`,
);
},
});
const { mutate: authorizeMutate, isPending: authorizeIsPending } =
useMutation({
mutationFn: () => {
return axios.post("/api/oidc/authorize-complete", {
ticket: screenParams.oidc_ticket,
});
},
mutationKey: ["authorize", screenParams.oidc_ticket],
onSuccess: (data) => {
toast.info(t("authorizeSuccessTitle"), {
description: t("authorizeSuccessSubtitle"),
});
window.location.replace(data.data.redirect_uri);
},
onError: (error) => {
window.location.replace(
`/error?error=${encodeURIComponent(error.message)}`,
);
},
});
useEffect(() => {
if (
!isOidc ||
screenParams.oidc_ticket === undefined ||
screenParams.oidc_scope === undefined ||
!auth.authenticated
) {
return;
}
if (screenParams.oidc_show_consent === false) {
authorizeMutate();
}
}, [
isOidc,
screenParams.oidc_ticket,
screenParams.oidc_scope,
screenParams.oidc_show_consent,
auth.authenticated,
authorizeMutate,
]);
if (
!isOidc ||
@@ -130,6 +154,19 @@ export const AuthorizePage = () => {
const scopes =
screenParams.oidc_scope.split(" ").filter((s) => s.trim() !== "") || [];
if (screenParams.oidc_show_consent === false) {
return (
<Card>
<CardHeader className="gap-1.5">
<CardTitle className="text-xl">Authorizing</CardTitle>
<CardDescription>
You will soon be redirected to your application...
</CardDescription>
</CardHeader>
</Card>
);
}
return (
<Card>
<CardHeader className="mb-2">
@@ -171,15 +208,12 @@ export const AuthorizePage = () => {
</CardContent>
)}
<CardFooter className="flex flex-col items-stretch gap-3">
<Button
onClick={() => authorizeMutation.mutate()}
loading={authorizeMutation.isPending}
>
<Button onClick={() => authorizeMutate()} loading={authorizeIsPending}>
{t("authorizeTitle")}
</Button>
<Button
onClick={() => navigate(`/logout${compiledParams}`)}
disabled={authorizeMutation.isPending}
disabled={authorizeIsPending}
variant="outline"
>
{t("cancelTitle")}