Add OIDC admin config page with auto-signup toggle
Backend: add autoSignup field to OidcConfig, ClickHouse schema, repository, and admin controller. Gate OIDC login when auto-signup is disabled and user is not pre-created (returns 403). Frontend: add OIDC admin page with full CRUD (save/test/delete), role-gated Admin nav link parsed from JWT, and matching design system styles. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ interface AuthState {
|
||||
accessToken: string | null;
|
||||
refreshToken: string | null;
|
||||
username: string | null;
|
||||
roles: string[];
|
||||
isAuthenticated: boolean;
|
||||
error: string | null;
|
||||
loading: boolean;
|
||||
@@ -13,6 +14,15 @@ interface AuthState {
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
function parseRolesFromJwt(token: string): string[] {
|
||||
try {
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
return Array.isArray(payload.roles) ? payload.roles : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function loadTokens() {
|
||||
return {
|
||||
accessToken: localStorage.getItem('cameleer-access-token'),
|
||||
@@ -39,6 +49,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
accessToken: initial.accessToken,
|
||||
refreshToken: initial.refreshToken,
|
||||
username: initial.username,
|
||||
roles: initial.accessToken ? parseRolesFromJwt(initial.accessToken) : [],
|
||||
isAuthenticated: !!initial.accessToken,
|
||||
error: null,
|
||||
loading: false,
|
||||
@@ -61,6 +72,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
accessToken,
|
||||
refreshToken,
|
||||
username,
|
||||
roles: parseRolesFromJwt(accessToken),
|
||||
isAuthenticated: true,
|
||||
loading: false,
|
||||
});
|
||||
@@ -88,6 +100,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
set({
|
||||
accessToken: data.accessToken,
|
||||
refreshToken: data.refreshToken,
|
||||
roles: parseRolesFromJwt(data.accessToken),
|
||||
isAuthenticated: true,
|
||||
});
|
||||
return true;
|
||||
@@ -102,6 +115,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
accessToken: null,
|
||||
refreshToken: null,
|
||||
username: null,
|
||||
roles: [],
|
||||
isAuthenticated: false,
|
||||
error: null,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user