feat(reui): update ReUI components and documentation
- Added new OIDC configuration options in `.env.example`. - Expanded documentation in `AGENTS.md` to include OIDC endpoints and admin UI. - Updated ReUI skill version and component count from 17 to 20 across various documentation files. - Enhanced `README.md` and other related files to reflect the new component structure and usage guidelines. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
cc38bf06f8
commit
0b6fa65b08
61 files changed
+2387
-103
No files matched your search
+54
-11
@@ -1,8 +1,10 @@
|
||||
import {
|
||||
buildSsoRedirectUrl,
|
||||
isJwtExpired,
|
||||
isPortalOidcAuthorizeUrl,
|
||||
isReturnToAllowed,
|
||||
readJwtPayload,
|
||||
type AppAuthMode,
|
||||
type LoginResponse,
|
||||
type MeResponse,
|
||||
} from '@authportal/shared'
|
||||
@@ -14,11 +16,23 @@ export const DEFAULT_RETURN_TO_ALLOWLIST =
|
||||
'.shnt.top,localhost,private,http://localhost:5173'
|
||||
|
||||
let returnToAllowlist: string | null = null
|
||||
let issuerUrl: string | null = null
|
||||
let returnToAllowlistPromise: Promise<string> | null = null
|
||||
|
||||
export async function ensureReturnToAllowlist(): Promise<string> {
|
||||
if (returnToAllowlist) return returnToAllowlist
|
||||
if (returnToAllowlistPromise) return returnToAllowlistPromise
|
||||
export async function ensureAuthConfig(): Promise<{
|
||||
returnToAllowlist: string
|
||||
issuer: string
|
||||
}> {
|
||||
if (returnToAllowlist && issuerUrl) {
|
||||
return { returnToAllowlist, issuer: issuerUrl }
|
||||
}
|
||||
if (returnToAllowlistPromise) {
|
||||
await returnToAllowlistPromise
|
||||
return {
|
||||
returnToAllowlist: returnToAllowlist ?? DEFAULT_RETURN_TO_ALLOWLIST,
|
||||
issuer: issuerUrl ?? 'https://auth.shnt.top',
|
||||
}
|
||||
}
|
||||
|
||||
returnToAllowlistPromise = (async () => {
|
||||
const fromVite = import.meta.env.VITE_RETURN_TO_ALLOWLIST as
|
||||
@@ -27,22 +41,38 @@ export async function ensureReturnToAllowlist(): Promise<string> {
|
||||
try {
|
||||
const res = await fetch('/api/v1/auth/config')
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as { return_to_allowlist?: string }
|
||||
const data = (await res.json()) as {
|
||||
return_to_allowlist?: string
|
||||
issuer?: string
|
||||
}
|
||||
if (data.return_to_allowlist) {
|
||||
returnToAllowlist = data.return_to_allowlist
|
||||
return returnToAllowlist
|
||||
}
|
||||
if (data.issuer) {
|
||||
issuerUrl = data.issuer
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
returnToAllowlist = fromVite || DEFAULT_RETURN_TO_ALLOWLIST
|
||||
returnToAllowlist =
|
||||
returnToAllowlist || fromVite || DEFAULT_RETURN_TO_ALLOWLIST
|
||||
issuerUrl = issuerUrl || 'https://auth.shnt.top'
|
||||
return returnToAllowlist
|
||||
})().finally(() => {
|
||||
returnToAllowlistPromise = null
|
||||
})
|
||||
|
||||
return returnToAllowlistPromise
|
||||
await returnToAllowlistPromise
|
||||
return {
|
||||
returnToAllowlist: returnToAllowlist!,
|
||||
issuer: issuerUrl!,
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureReturnToAllowlist(): Promise<string> {
|
||||
const cfg = await ensureAuthConfig()
|
||||
return cfg.returnToAllowlist
|
||||
}
|
||||
|
||||
export function getToken(): string | null {
|
||||
@@ -106,9 +136,16 @@ export async function reissueAccessToken(): Promise<LoginResponse> {
|
||||
return body
|
||||
}
|
||||
|
||||
/** SSO open: fresh JWT → app /auth/callback. */
|
||||
export async function ssoOpenApp(appBaseUrl: string): Promise<void> {
|
||||
/** SSO open: JWT fragment → /auth/callback, or plain URL for OIDC apps. */
|
||||
export async function ssoOpenApp(
|
||||
appBaseUrl: string,
|
||||
authMode: AppAuthMode = 'jwt',
|
||||
): Promise<void> {
|
||||
const base = appBaseUrl.replace(/\/$/, '')
|
||||
if (authMode === 'oidc') {
|
||||
window.location.href = base
|
||||
return
|
||||
}
|
||||
const issued = await reissueAccessToken()
|
||||
const callback = `${base}/auth/callback`
|
||||
window.location.href = buildSsoRedirectUrl(
|
||||
@@ -118,10 +155,16 @@ export async function ssoOpenApp(appBaseUrl: string): Promise<void> {
|
||||
)
|
||||
}
|
||||
|
||||
/** SSO return_to handoff with fresh JWT. */
|
||||
/** SSO return_to handoff with fresh JWT (or clean redirect for OIDC authorize). */
|
||||
export async function ssoHandoffReturnTo(returnTo: string): Promise<boolean> {
|
||||
const allowlist = await ensureReturnToAllowlist()
|
||||
const { returnToAllowlist: allowlist, issuer } = await ensureAuthConfig()
|
||||
if (!isReturnToAllowed(returnTo, allowlist)) return false
|
||||
|
||||
if (isPortalOidcAuthorizeUrl(returnTo, issuer)) {
|
||||
window.location.href = returnTo
|
||||
return true
|
||||
}
|
||||
|
||||
const issued = await reissueAccessToken()
|
||||
try {
|
||||
const token = getToken()
|
||||
|
||||
Reference in new issue
Block a user