fix(oauth): align custom binding response fields in frontend (#6818)

* fix(oauth): align custom binding response fields in frontend

* fix(oauth): restore custom access policy guidance
This commit is contained in:
Seefs
2026-08-15 13:56:06 +08:00
committed by GitHub
parent 4442bb3028
commit 116255f076
14 changed files with 216 additions and 45 deletions
+3 -9
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import type { PermissionCatalog } from '@/lib/admin-permissions'
import { api } from '@/lib/api'
import type { CustomOAuthBinding } from '@/lib/oauth'
import type {
User,
@@ -178,19 +179,12 @@ export async function getPermissionCatalog(): Promise<PermissionCatalog> {
// Admin Binding Management APIs
// ============================================================================
export interface OAuthBinding {
provider_id: string
provider_name: string
user_id?: number
external_id?: string
}
/**
* Get user's custom OAuth bindings (admin)
*/
export async function getUserOAuthBindings(
userId: number
): Promise<ApiResponse<OAuthBinding[]>> {
): Promise<ApiResponse<CustomOAuthBinding[]>> {
const res = await api.get(`/api/user/${userId}/oauth/bindings`)
return res.data
}
@@ -211,7 +205,7 @@ export async function adminClearUserBinding(
*/
export async function adminUnbindCustomOAuth(
userId: number,
providerId: string
providerId: number
): Promise<ApiResponse> {
const res = await api.delete(
`/api/user/${userId}/oauth/bindings/${providerId}`
@@ -45,13 +45,13 @@ import {
TooltipTrigger,
} from '@/components/ui/tooltip'
import { api } from '@/lib/api'
import { indexCustomOAuthBindings, type CustomOAuthBinding } from '@/lib/oauth'
import {
getUser,
getUserOAuthBindings,
adminClearUserBinding,
adminUnbindCustomOAuth,
type OAuthBinding,
} from '../../api'
import type { User } from '../../types'
@@ -68,7 +68,7 @@ interface BindingItem {
icon: React.ReactNode
value: string
type: 'builtin' | 'custom'
providerId?: string
providerId?: number
isBound: boolean
isEnabled: boolean
}
@@ -81,7 +81,7 @@ interface StatusInfo {
telegram_oauth?: boolean
linuxdo_oauth?: boolean
custom_oauth_providers?: Array<{
id: string
id: number
name: string
icon?: string
}>
@@ -162,7 +162,7 @@ function CustomProviderIcon(props: { iconUrl?: string }) {
export function UserBindingDialog(props: Props) {
const { t } = useTranslation()
const [user, setUser] = useState<User | null>(null)
const [oauthBindings, setOauthBindings] = useState<OAuthBinding[]>([])
const [oauthBindings, setOauthBindings] = useState<CustomOAuthBinding[]>([])
const [statusInfo, setStatusInfo] = useState<StatusInfo>({})
const [loading, setLoading] = useState(false)
const [showBoundOnly, setShowBoundOnly] = useState(true)
@@ -191,7 +191,7 @@ export function UserBindingDialog(props: Props) {
setUser(userRes.data)
}
if (oauthRes.success && oauthRes.data) {
setOauthBindings(oauthRes.data as OAuthBinding[])
setOauthBindings(oauthRes.data)
}
if (statusRes.success && statusRes.data) {
setStatusInfo(statusRes.data as StatusInfo)
@@ -236,37 +236,35 @@ export function UserBindingDialog(props: Props) {
})
}
const oauthBindingMap = new Map(
oauthBindings.map((b) => [String(b.provider_id), b])
)
const oauthBindingMap = indexCustomOAuthBindings(oauthBindings)
const customProviders = statusInfo.custom_oauth_providers || []
const seenProviderIds = new Set<string>()
const seenProviderIds = new Set<number>()
for (const provider of customProviders) {
seenProviderIds.add(String(provider.id))
const binding = oauthBindingMap.get(String(provider.id))
seenProviderIds.add(provider.id)
const binding = oauthBindingMap.get(provider.id)
items.push({
key: `oauth_${provider.id}`,
label: provider.name || provider.id,
label: provider.name || String(provider.id),
icon: <CustomProviderIcon iconUrl={provider.icon} />,
value: binding?.external_id || '',
value: binding?.provider_user_id || '',
type: 'custom',
providerId: String(provider.id),
providerId: provider.id,
isBound: !!binding,
isEnabled: true,
})
}
for (const binding of oauthBindings) {
if (!seenProviderIds.has(String(binding.provider_id))) {
if (!seenProviderIds.has(binding.provider_id)) {
items.push({
key: `oauth_${binding.provider_id}`,
label: binding.provider_name || binding.provider_id,
label: binding.provider_name || String(binding.provider_id),
icon: <Link2 className='h-4 w-4' />,
value: binding.external_id || '-',
value: binding.provider_user_id || '-',
type: 'custom',
providerId: String(binding.provider_id),
providerId: binding.provider_id,
isBound: true,
isEnabled: false,
})