/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
For commercial licensing, please contact support@quantumnous.com
*/
import type { PermissionCatalog } from '@/lib/admin-permissions'
import { api } from '@/lib/api'
import type {
User,
GetUsersParams,
GetUsersResponse,
SearchUsersParams,
UserFormData,
ManageUserAction,
ManageUserQuotaPayload,
ApiResponse,
} from './types'
// ============================================================================
// User Management APIs
// ============================================================================
/**
* Get paginated users list
*/
export async function getUsers(
params: GetUsersParams = {}
): Promise {
const { p = 1, page_size = 10, sort_by, sort_order } = params
const res = await api.get('/api/user/', {
params: {
p,
page_size,
sort_by,
sort_order,
},
})
return res.data
}
/**
* Search users by keyword or group
*/
export async function searchUsers(
params: SearchUsersParams
): Promise {
const {
keyword = '',
group = '',
role = '',
status = '',
p = 1,
page_size = 10,
sort_by,
sort_order,
} = params
const queryParams = new URLSearchParams()
queryParams.set('keyword', keyword)
queryParams.set('group', group)
if (role) queryParams.set('role', role)
if (status) queryParams.set('status', status)
queryParams.set('p', String(p))
queryParams.set('page_size', String(page_size))
if (sort_by) queryParams.set('sort_by', sort_by)
if (sort_order) queryParams.set('sort_order', sort_order)
const res = await api.get(`/api/user/search?${queryParams.toString()}`)
return res.data
}
/**
* Get single user by ID
*/
export async function getUser(id: number): Promise> {
const res = await api.get(`/api/user/${id}`)
return res.data
}
/**
* Create a new user
*/
export async function createUser(
data: UserFormData
): Promise> {
const res = await api.post('/api/user/', data)
return res.data
}
/**
* Update an existing user
*/
export async function updateUser(
data: UserFormData & { id: number }
): Promise>> {
const res = await api.put('/api/user/', data)
return res.data
}
/**
* Delete a single user (hard delete)
*/
export async function deleteUser(id: number): Promise {
const res = await api.delete(`/api/user/${id}/`)
return res.data
}
/**
* Manage user (promote, demote, enable, disable, delete)
*/
export async function manageUser(
id: number,
action: ManageUserAction
): Promise>> {
const res = await api.post('/api/user/manage', { id, action })
return res.data
}
/**
* Adjust user quota atomically (add/subtract/override)
*/
export async function adjustUserQuota(
payload: ManageUserQuotaPayload
): Promise>> {
const res = await api.post('/api/user/manage', payload)
return res.data
}
/**
* Reset user's Passkey registration
*/
export async function resetUserPasskey(id: number): Promise {
const res = await api.delete(`/api/user/${id}/reset_passkey`)
return res.data
}
/**
* Reset user's Two-Factor Authentication setup
*/
export async function resetUserTwoFA(id: number): Promise {
const res = await api.delete(`/api/user/${id}/2fa`)
return res.data
}
/**
* Get all available groups
*/
export async function getGroups(): Promise> {
const res = await api.get('/api/group/')
return res.data
}
/**
* Get the permission catalog (resources, actions, and role baselines).
* Source of truth lives in the backend authz package.
*/
export async function getPermissionCatalog(): Promise {
const res = await api.get('/api/authz/catalog')
return {
resources: res.data?.data?.resources ?? [],
roles: res.data?.data?.roles ?? [],
}
}
// ============================================================================
// 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> {
const res = await api.get(`/api/user/${userId}/oauth/bindings`)
return res.data
}
/**
* Clear a user's built-in binding (admin)
*/
export async function adminClearUserBinding(
userId: number,
bindingType: string
): Promise {
const res = await api.delete(`/api/user/${userId}/bindings/${bindingType}`)
return res.data
}
/**
* Unbind custom OAuth for a user (admin)
*/
export async function adminUnbindCustomOAuth(
userId: number,
providerId: string
): Promise {
const res = await api.delete(
`/api/user/${userId}/oauth/bindings/${providerId}`
)
return res.data
}