import { BaseController, Ok } from '@spinajs/http'; import { IFilterRequest, OrderDTO, PaginationDTO } from '@spinajs/orm-http'; import { User } from '@spinajs/rbac'; import { RoleGuard } from '../../interfaces.js'; import '../../services/RoleGuard.js'; export declare class CreateUserDto { Login: string; Email: string; Role: string | string[]; Metadata?: { [key: string]: any; }; constructor(data: Partial); } /** * PATCH body. Separate from {@link CreateUserDto} because the two have opposite * requirements: creation needs all three fields, an update needs none of them. * Sharing one schema made every documented partial update fail validation with * a 400 before the handler ever ran. * * Metadata is deliberately absent — it is managed through the dedicated * `/user/:uuid/metadata` routes, which validate one entry at a time and can * refuse the keys that decide account access. */ export declare class UpdateUserDto { Login?: string; Email?: string; Role?: string | string[]; constructor(data: Partial); } /** * User account management (admin). * Full CRUD operations for user accounts. Supports pagination, sorting, filtering, * and optional relation loading. All write operations require full authorization. * @tags Admin Users */ export declare class Users extends BaseController { protected RoleGuard: RoleGuard; /** * List users (admin) * Returns a paginated, sortable, filterable list of all users. Supports optional inclusion * of related Metadata. The total user count (matching current filters) is returned in the * X-Total-Count response header. * Filterable fields: Uuid (eq), Email (eq, like), Login (eq, like), CreatedAt, LastLoginAt, * DeletedAt (eq, gte, lte, lt, gt, isnull, notnull), IsActive (eq), Role (eq, neq), * user:niceName metadata (eq, neq, like). * @security cookieAuth * @param pagination.page Page number (zero-based) * @param pagination.limit Number of users per page (default: 10, max: 100) * @param order.column Column to sort by (default: CreatedAt). One of Uuid, Login, Email, Role, IsActive, CreatedAt, LastLoginAt, DeletedAt * @param order.order Sort direction: ASC or DESC (default: DESC) * @param include Relations to include — currently supports: Metadata * @returns {User[]} Paginated list of user accounts, each with optional Metadata relation * @response 400 Sort column is not sortable * @response 401 Unauthorized — valid session required * @response 403 Forbidden — readAny permission required on users resource */ list(pagination?: PaginationDTO, order?: OrderDTO, include?: string[], filter?: IFilterRequest): Promise[]>>; /** * List assignable roles (admin) * Returns the roles the calling administrator is allowed to grant, as decided by the * configured role guard — the system role and anything granting more than the caller * holds are left out, so a UI cannot offer an operation the guard will refuse. * @security cookieAuth * @returns {string[]} Role names the caller may assign * @response 401 Unauthorized — valid session required * @response 403 Forbidden — readAny permission required on users resource */ assignableRoles(actor: User): Promise>; /** * Get user by UUID (admin) * Retrieves a single user record by UUID. Supports optional inclusion of related Metadata. * @security cookieAuth * @param user User UUID path parameter * @param include Relations to include — currently supports: Metadata * @returns {User} User account with optional Metadata relation * @response 401 Unauthorized — valid session required * @response 403 Forbidden — readAny permission required on users resource * @response 404 User not found */ getSingleUser(user: User, include?: string[]): Promise>>; /** * Get user by login (admin) * Retrieves a single user record by login name. Supports optional inclusion of related Metadata. * @security cookieAuth * @param user User login name path parameter * @param include Relations to include — currently supports: Metadata * @returns {User} User account with optional Metadata relation * @response 401 Unauthorized — valid session required * @response 403 Forbidden — readAny permission required on users resource * @response 404 User not found */ getByLogin(user: User, include?: string[]): Promise>>; /** * Create user (admin) * Creates a new user account with a system-generated temporary password. The account is * created inactive and the temporary password is never returned: a single-use password-reset * link is mailed to the address instead, so the owner sets their own password and nothing * has to travel back through an administrator. Activate the account once they have. * `Role` takes one role name or a list of them; every entry is checked by the role guard, and * one refused entry refuses the whole request. * @security cookieAuth * @returns {User} Created user account * @response 400 Validation error — missing required fields, invalid format, an empty or unknown role, or a protected metadata key * @response 401 Unauthorized — valid session required * @response 403 Forbidden — createAny permission required, or a requested role grants more than the caller holds * @response 409 Login or email already in use, naming the clashing field in `parameter` */ addUser(actor: User, data: CreateUserDto): Promise>>; /** * Update user (admin) * Partially updates a user account. All fields are optional — only provided fields are changed. * Metadata is NOT handled here; use the `/user/:uuid/metadata` routes. * `Role` takes one role name or a list of them and REPLACES the account's whole role list, so * an entry left out is revoked and goes through the revoke half of the role guard. An empty * list is refused rather than applied. * @security cookieAuth * @param user User UUID path parameter * @response 200 User updated successfully * @response 400 Validation error — invalid field format, an empty role list or an unknown role * @response 401 Unauthorized — valid session required * @response 403 Forbidden — updateAny permission required, or the role change is refused by the role guard * @response 409 Login or email already in use by another account, naming the clashing field in `parameter` * @response 404 User not found */ updateUser(actor: User, user: User, data: UpdateUserDto): Promise>; /** * Delete user (admin) * Soft-deletes the account (`DeletedAt` is stamped, the row is kept) and destroys every * session it holds, so a deleted user stops acting immediately rather than when their * cookie happens to expire. * @security cookieAuth * @param user User UUID path parameter * @response 200 User deleted * @response 401 Unauthorized — valid session required * @response 403 Forbidden — deleteAny permission required, or the deletion is refused by the role guard * @response 404 User not found */ removeUser(actor: User, user: User): Promise>; /** * Restore a deleted user (admin) * Clears `DeletedAt` on a soft-deleted account. The account keeps its previous * `IsActive` state — restoring is not activating. * @security cookieAuth * @param uuid User UUID path parameter * @response 200 User restored * @response 400 User is not deleted * @response 401 Unauthorized — valid session required * @response 403 Forbidden — deleteAny permission required on users resource * @response 404 User not found */ restoreUser(uuid: string): Promise>; /** * Runs `work`, turning rbac's duplicate-account refusal into the 409 this API * has always answered. * * rbac throws a transport-agnostic {@link UserAlreadyExists} — it has no business * knowing about status codes — so the translation belongs here. `__handle_error__` * looks the response up by `err.constructor.name`, which is why this rethrows a * plain {@link ResourceDuplicated} rather than a subclass: a subclass would miss * the 409 mapping entirely and answer 500. * * The 409 carries WHICH field clashed, not only that something did. The error * body is built by spreading the thrown exception's own enumerable properties * (`__handle_error__`, @spinajs/http), so `parameter` reaches the client * alongside `message` in the shape {@link ValidationFailed} already uses for * schema rejections — an ajv-style entry per offending field. A form can then * mark the Email input rather than showing "something is already in use" * somewhere off to the side. */ protected asDuplicateResponse(work: () => Promise): Promise; /** * The requested sort column, or the default. Rejects anything outside * {@link SORTABLE_COLUMNS}. */ protected sortColumn(order?: OrderDTO): string; } //# sourceMappingURL=Users.d.ts.map