From 766a7287e38344a126bed2a385d628f85e91eddc Mon Sep 17 00:00:00 2001 From: Stavros Date: Thu, 27 Aug 2026 17:08:08 +0300 Subject: [PATCH 1/3] fix: consent screen skip status should get checked after auth --- frontend/src/pages/authorize-page.tsx | 41 +++++---- internal/controller/controller.go | 5 ++ internal/controller/oidc_controller.go | 110 +++++++++++++++++++++---- internal/service/oidc_service.go | 11 +++ 4 files changed, 134 insertions(+), 33 deletions(-) diff --git a/frontend/src/pages/authorize-page.tsx b/frontend/src/pages/authorize-page.tsx index 730e5f27b..562061b45 100644 --- a/frontend/src/pages/authorize-page.tsx +++ b/frontend/src/pages/authorize-page.tsx @@ -1,5 +1,5 @@ import { useUserContext } from "@/context/user-context"; -import { useMutation } from "@tanstack/react-query"; +import {useMutation} from "@tanstack/react-query"; import { Navigate, useNavigate } from "react-router"; import { useLocation } from "react-router"; import { @@ -25,7 +25,8 @@ import { searchParamsFromObject, useScreenParams, } from "@/lib/hooks/screen-params"; -import { useEffect } from "react"; +import {useEffect, useState} from "react"; +import { z } from "zod"; type Scope = { id: string; @@ -34,6 +35,10 @@ type Scope = { icon: React.ReactNode; }; +const skipConsentResponseSchema = z.object({ + skipConsent: z.boolean(), +}) + const scopeMapIconProps = { className: "stroke-muted-foreground stroke-[1.75] h-4", }; @@ -96,14 +101,7 @@ export const AuthorizePage = () => { } return ""; })(); - - // TODO: maybe a better way to do this - const shouldAutoAuthorize = - auth.authenticated && - isOidc && - screenParams.oidc_ticket !== undefined && - screenParams.oidc_scope !== undefined && - screenParams.oidc_prompt === "none"; + const [autoAuthorize, setAutoAuthorize] = useState(false); const { mutate: authorizeMutate, isPending: authorizePending } = useMutation({ mutationFn: () => { @@ -126,10 +124,21 @@ export const AuthorizePage = () => { }); useEffect(() => { - if (shouldAutoAuthorize) { - authorizeMutate(); - } - }, [shouldAutoAuthorize, authorizeMutate]); + const checkSkipConsent = async () => { + try { + const res = await fetch( + `/api/oidc/skip-consent?oidc_ticket=${encodeURIComponent(screenParams.oidc_ticket ?? "")}`, + ); + if (!res.ok) return; + const parsed = skipConsentResponseSchema.safeParse(await res.json()); + if (!parsed.success || !parsed.data.skipConsent) return; + setAutoAuthorize(true); + authorizeMutate(); + } catch {} + }; + + checkSkipConsent(); + }, []); if (!isOidc || !screenParams.oidc_ticket || !screenParams.oidc_scope) { return ( @@ -190,13 +199,13 @@ export const AuthorizePage = () => { diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index cc5214a39..214baadad 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ plugins: [react(), tailwindcss(), visualizer()], resolve: { alias: { - "@": path.resolve(__dirname, "./src"), + "@": path.resolve(import.meta.dirname, "./src"), }, }, build: { diff --git a/internal/controller/oidc_controller.go b/internal/controller/oidc_controller.go index 0f13709cf..99fd78f2f 100644 --- a/internal/controller/oidc_controller.go +++ b/internal/controller/oidc_controller.go @@ -266,6 +266,9 @@ func (controller *OIDCController) authorize(c *gin.Context) { } func (controller *OIDCController) skipConsent(c *gin.Context) { + c.Header("cache-control", "no-store") + c.Header("pragma", "no-cache") + if controller.oidc == nil { c.JSON(500, SimpleResponse{ Status: 500,