2026-04-01 00:42:25 +08:00
|
|
|
/**
|
|
|
|
|
* 认证相关 API
|
|
|
|
|
*/
|
|
|
|
|
|
2026-04-01 22:10:24 +08:00
|
|
|
async function parseErrorDetail(response, fallbackMessage) {
|
|
|
|
|
const contentType = response.headers.get('content-type') || ''
|
|
|
|
|
|
|
|
|
|
if (contentType.includes('application/json')) {
|
|
|
|
|
const error = await response.json()
|
|
|
|
|
return error?.detail || fallbackMessage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const text = (await response.text()).trim()
|
|
|
|
|
return text || fallbackMessage
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 00:42:25 +08:00
|
|
|
/**
|
|
|
|
|
* 获取 OIDC 配置
|
|
|
|
|
* @returns {Promise<{enabled: boolean, provider_name?: string}>}
|
|
|
|
|
*/
|
|
|
|
|
async function getOIDCConfig() {
|
|
|
|
|
const response = await fetch('/api/auth/oidc/config')
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error('获取 OIDC 配置失败')
|
|
|
|
|
}
|
|
|
|
|
return response.json()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取 OIDC 登录 URL
|
|
|
|
|
* @param {string} redirectPath - 登录后的重定向路径
|
|
|
|
|
* @returns {Promise<{login_url: string}>}
|
|
|
|
|
*/
|
|
|
|
|
async function getOIDCLoginUrl(redirectPath = '/') {
|
|
|
|
|
const params = new URLSearchParams({ redirect_path: redirectPath })
|
|
|
|
|
const response = await fetch(`/api/auth/oidc/login-url?${params}`)
|
|
|
|
|
if (!response.ok) {
|
2026-04-01 22:10:24 +08:00
|
|
|
const detail = await parseErrorDetail(response, '获取 OIDC 登录地址失败')
|
|
|
|
|
throw new Error(detail)
|
2026-04-01 00:42:25 +08:00
|
|
|
}
|
|
|
|
|
return response.json()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2026-04-01 22:10:24 +08:00
|
|
|
* 使用一次性 code 交换 OIDC 登录结果
|
|
|
|
|
* @param {string} code - 一次性登录 code
|
2026-04-01 00:42:25 +08:00
|
|
|
* @returns {Promise<{
|
|
|
|
|
* access_token: string,
|
|
|
|
|
* token_type: string,
|
|
|
|
|
* user_id: number,
|
|
|
|
|
* username: string,
|
|
|
|
|
* user_id_login: string,
|
|
|
|
|
* phone_number: string | null,
|
|
|
|
|
* avatar: string | null,
|
|
|
|
|
* role: string,
|
|
|
|
|
* department_id: number | null,
|
|
|
|
|
* department_name: string | null
|
|
|
|
|
* }>}
|
|
|
|
|
*/
|
2026-04-01 22:10:24 +08:00
|
|
|
async function exchangeOIDCCode(code) {
|
|
|
|
|
const response = await fetch('/api/auth/oidc/exchange-code', {
|
2026-04-01 00:42:25 +08:00
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
2026-04-01 22:10:24 +08:00
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ code })
|
2026-04-01 00:42:25 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (!response.ok) {
|
2026-04-01 22:10:24 +08:00
|
|
|
const detail = await parseErrorDetail(response, 'OIDC 登录失败')
|
|
|
|
|
throw new Error(detail)
|
2026-04-01 00:42:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response.json()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const authApi = {
|
|
|
|
|
getOIDCConfig,
|
|
|
|
|
getOIDCLoginUrl,
|
2026-04-06 12:09:22 +08:00
|
|
|
exchangeOIDCCode
|
2026-04-01 00:42:25 +08:00
|
|
|
}
|