Add OIDC logout, fix OpenAPI schema types, expose end_session_endpoint
All checks were successful
CI / build (push) Successful in 1m8s
CI / docker (push) Successful in 51s
CI / deploy (push) Successful in 29s

Backend:
- Expose end_session_endpoint from OIDC provider metadata in /auth/oidc/config
- Add getEndSessionEndpoint() to OidcTokenExchanger

Frontend:
- On OIDC logout, redirect to provider's end_session_endpoint to clear SSO session
- Strip /api/v1 prefix from OpenAPI paths to match client baseUrl convention
- Add schema-types.ts with convenience type re-exports from generated schema
- Fix all type imports to use schema-types instead of raw generated schema
- Fix optional field access (processors, children, duration) with proper typing
- Fix AgentInstance.state → status field name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-14 14:43:18 +01:00
parent 0d82304cf0
commit 50bb22d6f6
15 changed files with 1755 additions and 53 deletions

View File

@@ -22,6 +22,9 @@ export function LoginPage() {
.then((data) => {
if (data?.authorizationEndpoint && data?.clientId) {
setOidc({ clientId: data.clientId, authorizationEndpoint: data.authorizationEndpoint });
if (data.endSessionEndpoint) {
localStorage.setItem('cameleer-oidc-end-session', data.endSessionEndpoint);
}
}
})
.catch(() => {});

View File

@@ -68,6 +68,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
throw new Error(body.message || 'Invalid credentials');
}
const { accessToken, refreshToken } = await res.json();
localStorage.removeItem('cameleer-oidc-end-session');
persistTokens(accessToken, refreshToken, username);
set({
accessToken,
@@ -143,7 +144,9 @@ export const useAuthStore = create<AuthState>((set, get) => ({
},
logout: () => {
const endSessionEndpoint = localStorage.getItem('cameleer-oidc-end-session');
clearTokens();
localStorage.removeItem('cameleer-oidc-end-session');
set({
accessToken: null,
refreshToken: null,
@@ -152,5 +155,12 @@ export const useAuthStore = create<AuthState>((set, get) => ({
isAuthenticated: false,
error: null,
});
if (endSessionEndpoint) {
const postLogoutRedirect = `${window.location.origin}/login`;
const params = new URLSearchParams({
post_logout_redirect_uri: postLogoutRedirect,
});
window.location.href = `${endSessionEndpoint}?${params}`;
}
},
}));