feat(auth): OIDC login UI + binding management + OIDC-only mode
- useAuthConfig fetches public /auth/config; LoginPage hides the password form when oidc_only and shows an SSO button when enabled. - /oidc/callback route applies the returned JWT (sign-in) or shows the link result; oidc_error surfaced on LoginPage. - UsersPage: hides password fields in OIDC-only mode; admin OIDC bind/unbind UI per user. Sidebar self-service "Link OIDC account" (non-OIDC_ONLY). - Dockerfile ARG/ENV HARBORFORGE_OIDC_ONLY. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||
import api from '@/services/api'
|
||||
import { useAuthConfig, oidcLinkHref } from '@/hooks/useAuthConfig'
|
||||
import type { User } from '@/types'
|
||||
|
||||
interface Props {
|
||||
@@ -11,6 +12,7 @@ interface Props {
|
||||
export default function Sidebar({ user, onLogout }: Props) {
|
||||
const { pathname } = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const { config: authCfg } = useAuthConfig()
|
||||
const [unreadCount, setUnreadCount] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -64,6 +66,11 @@ export default function Sidebar({ user, onLogout }: Props) {
|
||||
<button onClick={() => navigate('/login')}>Log in</button>
|
||||
)}
|
||||
</div>
|
||||
{user && authCfg.oidcEnabled && !authCfg.oidcOnly && (
|
||||
<div className="sidebar-footer" style={{ borderTop: 'none', paddingTop: 0 }}>
|
||||
<a href={oidcLinkHref()} title="Link your account to an OIDC identity">🔗 Link OIDC account</a>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user