87c2b04174
- 统一审批中心:模型/资源/渠道/工具四类申请聚合审批,通过自动开通 (marketplace 安装/渠道授权),outbox 双向站内信;门户可发起/撤回。 - 工具治理:rate_limit_rpm(固定窗口原子 upsert,多实例共享)+ approval_required (首次调用自动发起审批,批准前一律拒绝)。 - 平台环境变量:平台级注入 skill/MCP 运行时,个人可覆盖;系统管理员可写。 - 数字员工会话入口:门户列表/对话/调用记录,复用用户运行时凭据。 - 个人渠道:webhook 入站令牌 SHA-256 摘要 + constant-time 校验,绑定已批准 模型,用量归属用户 Key。 - 报表多维:工具调用/审批授权/安全事件三组统计端点与页面。 - 租户配额:部门 Key/月 Token 上限,运行时凭据开通强制校验,概览展示用量。 - 迁移 000042-000045;修复渠道空 API Key NOT NULL 违约与 inet 扫描; 25 包测试通过,前后端构建通过,端到端验证完成。
214 lines
5.4 KiB
TypeScript
214 lines
5.4 KiB
TypeScript
import request from '@/utils/http'
|
|
|
|
export type IdentityKind = 'admin' | 'portal'
|
|
|
|
export interface IdentityRecord {
|
|
id: string
|
|
kind: IdentityKind
|
|
login: string
|
|
display_name: string
|
|
role: string
|
|
permissions: string[]
|
|
effective_permissions: string[]
|
|
active: boolean
|
|
auth_source: string
|
|
totp_enabled: boolean
|
|
locked_until?: string
|
|
created_at: string
|
|
updated_at: string
|
|
department_id?: string
|
|
department_name?: string
|
|
}
|
|
|
|
export interface IdentityInput {
|
|
login: string
|
|
display_name: string
|
|
role: string
|
|
password?: string
|
|
permissions: string[]
|
|
active: boolean
|
|
department_id?: string
|
|
}
|
|
|
|
export interface DepartmentRecord {
|
|
id: string
|
|
code: string
|
|
name: string
|
|
description: string
|
|
parent_id?: string
|
|
parent_name?: string
|
|
active: boolean
|
|
max_api_keys: number
|
|
max_monthly_tokens: number
|
|
user_count: number
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface DepartmentInput {
|
|
code: string
|
|
name: string
|
|
description: string
|
|
parent_id?: string
|
|
active: boolean
|
|
max_api_keys?: number
|
|
max_monthly_tokens?: number
|
|
}
|
|
|
|
export interface IdentityProviderRecord {
|
|
id: string
|
|
code: string
|
|
display_name: string
|
|
issuer_url: string
|
|
client_id: string
|
|
secret_configured: boolean
|
|
redirect_uri: string
|
|
portal_return_url: string
|
|
scopes: string[]
|
|
auto_provision: boolean
|
|
default_department_id?: string
|
|
enabled: boolean
|
|
revision: number
|
|
credential_kek_version: number
|
|
}
|
|
|
|
export interface IdentityProviderInput {
|
|
code: string
|
|
display_name: string
|
|
issuer_url: string
|
|
client_id: string
|
|
client_secret?: string
|
|
redirect_uri: string
|
|
portal_return_url: string
|
|
scopes: string[]
|
|
auto_provision: boolean
|
|
default_department_id?: string
|
|
enabled: boolean
|
|
}
|
|
|
|
export interface SAMLProviderRecord {
|
|
id: string
|
|
kind: 'saml'
|
|
code: string
|
|
display_name: string
|
|
metadata_url: string
|
|
sp_entity_id: string
|
|
acs_url: string
|
|
portal_return_url: string
|
|
email_attribute: string
|
|
name_attribute: string
|
|
auto_provision: boolean
|
|
default_department_id?: string
|
|
enabled: boolean
|
|
revision: number
|
|
}
|
|
|
|
export type SAMLProviderInput = Omit<SAMLProviderRecord, 'id' | 'kind' | 'revision'>
|
|
|
|
function resource(kind: IdentityKind) {
|
|
return kind === 'admin' ? 'admins' : 'portal-users'
|
|
}
|
|
|
|
export function fetchIdentities(kind: IdentityKind) {
|
|
return request.get<IdentityRecord[]>({
|
|
url: `/api/v1/admin/identities/${resource(kind)}`
|
|
})
|
|
}
|
|
|
|
export function createIdentity(kind: IdentityKind, data: IdentityInput) {
|
|
return request.post<IdentityRecord>({
|
|
url: `/api/v1/admin/identities/${resource(kind)}`,
|
|
params: data
|
|
})
|
|
}
|
|
|
|
export function updateIdentity(kind: IdentityKind, id: string, data: IdentityInput) {
|
|
return request.put<IdentityRecord>({
|
|
url: `/api/v1/admin/identities/${resource(kind)}/${id}`,
|
|
params: data
|
|
})
|
|
}
|
|
|
|
export function fetchDepartments() {
|
|
return request.get<DepartmentRecord[]>({ url: '/api/v1/admin/departments' })
|
|
}
|
|
|
|
export function createDepartment(data: DepartmentInput) {
|
|
return request.post<DepartmentRecord>({ url: '/api/v1/admin/departments', params: data })
|
|
}
|
|
|
|
export function updateDepartment(id: string, data: DepartmentInput) {
|
|
return request.put<DepartmentRecord>({ url: `/api/v1/admin/departments/${id}`, params: data })
|
|
}
|
|
|
|
export function fetchIdentityProviders() {
|
|
return request.get<IdentityProviderRecord[]>({ url: '/api/v1/admin/identity-providers' })
|
|
}
|
|
|
|
export function createIdentityProvider(data: IdentityProviderInput) {
|
|
return request.post<IdentityProviderRecord>({ url: '/api/v1/admin/identity-providers', params: data })
|
|
}
|
|
|
|
export function updateIdentityProvider(id: string, data: IdentityProviderInput) {
|
|
return request.put<IdentityProviderRecord>({ url: `/api/v1/admin/identity-providers/${id}`, params: data })
|
|
}
|
|
|
|
export function fetchSAMLProviders() {
|
|
return request.get<SAMLProviderRecord[]>({ url: '/api/v1/admin/saml-providers' })
|
|
}
|
|
|
|
export function createSAMLProvider(data: SAMLProviderInput) {
|
|
return request.post<SAMLProviderRecord>({ url: '/api/v1/admin/saml-providers', params: data })
|
|
}
|
|
|
|
export function updateSAMLProvider(id: string, data: SAMLProviderInput) {
|
|
return request.put<SAMLProviderRecord>({ url: `/api/v1/admin/saml-providers/${id}`, params: data })
|
|
}
|
|
|
|
export interface SocialProviderRecord {
|
|
id: string
|
|
code: string
|
|
kind: 'wecom' | 'dingtalk' | 'feishu'
|
|
display_name: string
|
|
client_id: string
|
|
agent_id: string
|
|
secret_configured: boolean
|
|
redirect_uri: string
|
|
portal_return_url: string
|
|
auto_provision: boolean
|
|
default_department_id?: string
|
|
enabled: boolean
|
|
revision: number
|
|
created_at: string
|
|
updated_at: string
|
|
}
|
|
|
|
export interface SocialProviderInput {
|
|
code: string
|
|
display_name: string
|
|
client_id: string
|
|
agent_id?: string
|
|
secret?: string
|
|
redirect_uri: string
|
|
portal_return_url: string
|
|
auto_provision: boolean
|
|
default_department_id?: string
|
|
enabled: boolean
|
|
}
|
|
|
|
export function fetchSocialProviders() {
|
|
return request.get<SocialProviderRecord[]>({ url: '/api/v1/admin/social-providers' })
|
|
}
|
|
|
|
export function createSocialProvider(kind: string, data: SocialProviderInput) {
|
|
return request.post<SocialProviderRecord>({ url: '/api/v1/admin/social-providers', params: { kind }, data })
|
|
}
|
|
|
|
export function updateSocialProvider(kind: string, data: SocialProviderInput) {
|
|
return request.put<SocialProviderRecord>({ url: `/api/v1/admin/social-providers/${kind}`, params: data })
|
|
}
|
|
|
|
export function deleteSocialProvider(kind: string) {
|
|
return request.del({ url: `/api/v1/admin/social-providers/${kind}` })
|
|
}
|