| Phiên bản | 1.1.0 |
| URL Cơ sở | http://localhost:3001/api/auth |
| Hệ thống | Hệ thống Xác thực |
| Module | AUTH - Xác thực (Better Auth) |
| Ngày | 2026-08-05 |
| Tác giả | Nam Nguyen |
| SRS Liên quan | SRS Xác thực |
| Yêu cầu SRS | Đầu nối API |
|---|---|
| FR-001 Đăng ký Người dùng | POST /sign-up/email → RabbitMQ (verification.email) → Email Queue Worker → EMAIL module |
| FR-002 Đăng nhập | POST /sign-in/email, POST /sign-in/social, POST /sign-in/username |
| FR-003 Đăng xuất | POST /sign-out |
| FR-004 Làm mới Token | POST /refresh-token |
| FR-005 Đặt lại Mật khẩu (Email) | POST /request-password-reset → RabbitMQ (password.reset.email) → Email Queue Worker → EMAIL module |
| FR-006 Đặt lại Mật khẩu (Số điện thoại) | POST /request-password-reset → RabbitMQ (password.reset.sms) → SMS Queue Worker → SMS module |
| FR-007 Đổi Mật khẩu | POST /change-password |
| FR-008 Xác minh Email | GET /verify-email, POST /send-verification-email |
| FR-009 Xác minh Số điện thoại | POST /send-verification-sms (qua module SMS) |
| FR-010 Quản lý Người dùng | GET /admin/list-users, GET /admin/get-user, POST /admin/create-user, POST /admin/update-user, POST /admin/remove-user |
| FR-011 Quản lý Vai trò | POST /admin/set-role, POST /organization/create-role, POST /organization/update-role, POST /organization/delete-role |
| FR-012 Xác thực Xã hội | POST /sign-in/social, POST /link-social, POST /unlink-account |
| FR-013 Quản lý Phiên làm việc | GET /list-sessions, POST /revoke-session, POST /revoke-sessions, POST /revoke-other-sessions |
| FR-014 Khóa Tài khoản/Đăng nhập giả danh | POST /admin/ban-user, POST /admin/unban-user, POST /admin/impersonate-user |
| FR-015 Quản lý Tổ chức | POST /organization/create, POST /organization/update, POST /organization/delete, GET /organization/list |
| FR-016 Quản lý Nhóm | POST /organization/create-team, POST /organization/update-team, POST /organization/remove-team |
| FR-017 Quản lý Lời mời | POST /organization/invite-member, POST /organization/accept-invitation, POST /organization/reject-invitation |
| FR-018 Gửi lại Lời mời | POST /organization/resend-invitation |
| FR-019 Thu hồi Lời mời | DELETE /organization/cancel-invitation |
| FR-020 Xác minh Token Lời mời | GET /organization/verify-invitation |
Tất cả đầu nối yêu cầu một trong các phương thức sau:
apiKeyCookie (dựa trên cookie)Authorization: Bearer <token>Các đầu nối công khai (đăng ký, đăng nhập, yêu cầu đặt lại mật khẩu) không yêu cầu xác thực.
| Nhãn | Số lượng | Mô tả |
|---|---|---|
| Default | 31 | Xác thực cốt lõi: đăng ký, đăng nhập, phiên làm việc, mật khẩu, email, hồ sơ người dùng |
| Admin | 15 | Quản lý người dùng, khóa/mở khóa, đăng nhập giả danh, thu hồi phiên |
| Organization | 27 | CRUD tổ chức, thành viên, nhóm, lời mời, vai trò, quyền hạn |
| Jwt | 2 | JSON Web Key Set và các đầu nối JWT token |
{
"token": "eyJhbGciOiJSUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "[email protected]",
"emailVerified": true,
"role": "user",
"createdAt": "2026-07-24T10:30:00Z",
"updatedAt": "2026-07-24T10:30:00Z"
}
}
{
"message": "Invalid credentials"
}
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh duy nhất (UUID) |
| name | string | Có | Tên hiển thị của người dùng |
| string | Có | Địa chỉ email của người dùng | |
| emailVerified | boolean | Có | Liệu email đã được xác minh chưa (mặc định: false) |
| image | string | Không | URL ảnh hồ sơ |
| createdAt | datetime | Có | Thời điểm tạo tài khoản |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
| role | string | Có | Vai trò hệ thống: "user" hoặc "super_admin" (mặc định: "user") |
| banned | boolean | Không | Liệu người dùng có bị khóa không (mặc định: false) |
| banReason | string | Không | Lý do khóa tài khoản |
| banExpires | datetime | Không | Thời điểm hết hạn khóa |
Mô tả Vai trò Hệ thống:
| Vai trò | Mô tả | Tự đăng ký |
|---|---|---|
user | Tài khoản người dùng tiêu chuẩn (mặc định). Người dùng có thể tạo tổ chức và nhận vai trò cấp tổ chức (HR, Candidate, Employer). | Có (mặc định) |
super_admin | Quản trị viên hệ thống có quyền truy cập đầy đủ. Có thể quản lý tất cả người dùng, vai trò và tổ chức. | Không (chỉ tạo bởi admin qua POST /admin/create-user) |
Lưu ý: Các vai trò cấp tổ chức (HR, Candidate, Employer) được xác định theo từng tổ chức và được gán cho thành viên thông qua hệ thống vai trò tổ chức (xem phần 6.3). Chúng không phải là vai trò cấp hệ thống.
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh phiên |
| expiresAt | datetime | Có | Thời điểm hết hạn phiên |
| token | string | Có | Token phiên |
| createdAt | datetime | Có | Thời điểm tạo phiên |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
| ipAddress | string | Không | Địa chỉ IP của client |
| userAgent | string | Không | User agent của client |
| userId | string | Có | ID người dùng liên kết |
| impersonatedBy | string | Không | ID Admin nếu đang đăng nhập giả danh |
| activeOrganizationId | string | Không | ID tổ chức đang hoạt động |
| activeTeamId | string | Không | ID nhóm đang hoạt động |
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh tài khoản |
| accountId | string | Có | ID tài khoản của nhà cung cấp |
| providerId | string | Có | Định danh nhà cung cấp (ví dụ: "google", "github") |
| userId | string | Có | ID người dùng liên kết |
| accessToken | string | Không | Token truy cập OAuth |
| refreshToken | string | Không | Token làm mới OAuth |
| idToken | string | Không | OIDC ID token |
| accessTokenExpiresAt | datetime | Không | Thời hạn token truy cập |
| refreshTokenExpiresAt | datetime | Không | Thời hạn token làm mới |
| scope | string | Không | Phạm vi OAuth |
| password | string | Không | Băm mật khẩu (chỉ cho nhà cung cấp email) |
| createdAt | datetime | Có | Thời điểm tạo tài khoản |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh xác minh |
| identifier | string | Có | Đối tượng xác minh (email, số điện thoại) |
| value | string | Có | Giá trị xác minh (OTP, token) |
| expiresAt | datetime | Có | Thời hạn xác minh |
| createdAt | datetime | Có | Thời điểm tạo |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh tổ chức |
| name | string | Có | Tên tổ chức |
| slug | string | Có | Slug thân thiện với URL |
| logo | string | Không | URL logo |
| createdAt | datetime | Có | Thời điểm tạo |
| metadata | string | Không | Chuỗi metadata JSON |
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh nhóm |
| name | string | Có | Tên nhóm |
| organizationId | string | Có | ID tổ chức cha |
| createdAt | datetime | Có | Thời điểm tạo |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| id | string | Có | Định danh lời mời |
| organizationId | string | Có | ID tổ chức đích |
| string | Có | Email người được mời | |
| tokenHash | string | Không | Băm SHA-256 của token lời mời (không bao giờ hiển thị trong phản hồi) |
| role | string | Không | Vai trò được gán |
| teamId | string | Không | ID nhóm đích |
| employerId | string | Không | ID Employer (bắt buộc cho vai trò HR) |
| status | string | Có | Trạng thái: pending, accepted, rejected, canceled, expired, revoked |
| expiresAt | datetime | Có | Thời hạn lời mời |
| acceptedAt | datetime | Không | Thời điểm lời mời được chấp nhận |
| inviterId | string | Có | Người dùng đã gửi lời mời |
| createdAt | datetime | Có | Thời điểm tạo |
| updatedAt | datetime | Có | Thời điểm cập nhật cuối cùng |
Đăng ký người dùng mới bằng email và mật khẩu. Người dùng được gán vai trò hệ thống user theo mặc định.
Lưu ý: Tài khoản super_admin không thể tự đăng ký. Chúng phải được tạo bởi admin qua POST /admin/create-user.
Xử lý Bất đồng bộ: Sau khi tạo tài khoản, hệ thống publish sự kiện verification.email.requested lên RabbitMQ (queue: verification.email). Email queue worker bên trong AUTH service consume sự kiện và gọi EMAIL module để gửi email xác minh. Quá trình gửi email diễn ra bất đồng bộ — không chặn response trả về cho client.
Yêu cầu:
{
"name": "John Doe",
"email": "[email protected]",
"password": "securepassword123"
}
Các trường Yêu cầu:
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| name | string | Có | Tên hiển thị của người dùng (2-100 ký tự) |
| string | Có | Địa chỉ email duy nhất | |
| password | string | Có | Tối thiểu 8 ký tự, ít nhất 1 chữ hoa, 1 chữ thường, 1 chữ số |
| role | string | Không | Enum: "user" (mặc định). Chỉ "user" được phép cho tự đăng ký. |
Phản hồi 200:
{
"token": "eyJhbGciOiJSUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "[email protected]",
"emailVerified": false,
"role": "user",
"createdAt": "2026-08-05T10:30:00Z",
"updatedAt": "2026-08-05T10:30:00Z"
}
}
Lưu ý: Response trả về ngay sau khi tạo tài khoản. Email xác minh được gửi bất đồng bộ qua RabbitMQ — có thể mất vài giây đến vài phút. Người dùng có thể yêu cầu gửi lại qua POST /send-verification-email nếu không nhận được.
Lỗi 400 — Vai trò không hợp lệ:
{
"message": "Role must be 'user'. super_admin accounts are created by admin."
}
Đăng nhập bằng email và mật khẩu.
Yêu cầu:
{
"email": "[email protected]",
"password": "securepassword123"
}
Phản hồi 200:
{
"token": "eyJhbGciOiJSUzI1NiIs...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "John Doe",
"email": "[email protected]",
"emailVerified": true,
"role": "user"
}
}
Đăng nhập bằng nhà cung cấp xã hội (Google, GitHub, v.v.).
Yêu cầu:
{
"provider": "google",
"callbackURL": "http://localhost:3000/dashboard"
}
Phản hồi 200:
{
"url": "https://accounts.google.com/o/oauth2/auth?...",
"redirect": true
}
Các nhà cung cấp được hỗ trợ: apple, atlassian, cognito, discord, facebook, figma, github, microsoft, google, huggingface, slack, spotify, twitch, twitter, dropbox, kick, linear, linkedin, gitlab, tiktok, reddit, roblox, salesforce, vk, zoom, notion, kakao, naver, line, paybin, paypal, polar, railway, vercel, wechat
Đầu nối callback OAuth. Xử lý chuyển hướng từ các nhà cung cấp xã hội.
Callback OAuth với trao đổi mã.
Yêu cầu:
{
"code": "authorization_code",
"state": "csrf_state"
}
Lấy thông tin phiên hiện tại.
Phản hồi 200:
{
"session": {
"id": "session-123",
"expiresAt": "2026-08-12T10:30:00Z",
"token": "abc...",
"userId": "550e8400-e29b-41d4-a716-446655440000",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0..."
},
"user": { ... }
}
Lấy thông tin phiên hiện tại (biến thể POST).
Hủy bỏ phiên hiện tại.
Phản hồi 200: { "success": true }
Liệt kê tất cả các phiên đang hoạt động của người dùng hiện tại.
Phản hồi 200:
[
{
"id": "session-123",
"expiresAt": "2026-08-12T10:30:00Z",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"createdAt": "2026-08-05T10:30:00Z"
}
]
Thu hồi một phiên cụ thể.
Yêu cầu:
{
"sessionId": "session-123"
}
Thu hồi tất cả các phiên của người dùng hiện tại.
Thu hồi tất cả các phiên ngoại trừ phiên hiện tại.
Cập nhật metadata phiên (ví dụ: tổ chức đang hoạt động).
Yêu cầu:
{
"activeOrganizationId": "org-123"
}
Làm mới token truy cập bằng token làm mới.
Phản hồi 200:
{
"token": "eyJhbGciOiJSUzI1NiIs...",
"session": { ... }
}
Lấy token truy cập mới cho phiên hiện tại.
Đổi mật khẩu (yêu cầu mật khẩu hiện tại).
Yêu cầu:
{
"currentPassword": "oldpassword",
"newPassword": "newpassword123"
}
Yêu cầu đặt lại mật khẩu. Gửi liên kết đặt lại qua email (hoặc OTP qua SMS).
Xử lý Bất đồng bộ: Sau khi tạo reset token, hệ thống publish sự kiện password.reset.email.requested (hoặc password.reset.sms.requested) lên RabbitMQ. Email/SMS queue worker trong AUTH consume và gọi EMAIL/SMS module để gửi. Response trả về ngay — không chờ gửi xong.
Yêu cầu (Email):
{
"email": "[email protected]",
"redirectTo": "http://localhost:3000/reset-password"
}
Yêu cầu (SMS):
{
"phone": "+84901234567"
}
Phản hồi 200:
{
"message": "If the email exists, a reset link has been sent"
}
Lưu ý: Response luôn trả về 200 với cùng message để không tiết lộ email/SĐT có tồn tại hay không.
Callback đặt lại mật khẩu. Xác thực token đặt lại.
Hoàn tất đặt lại mật khẩu bằng token (email) hoặc OTP (SMS).
Yêu cầu (Email — dùng token):
{
"token": "reset-token-abc",
"newPassword": "newpassword123"
}
Yêu cầu (SMS — dùng OTP):
{
"otp": "123456",
"newPassword": "newpassword123"
}
Phản hồi 200:
{
"message": "Password reset successfully"
}
Lỗi 400 — Token/OTP không hợp lệ:
{
"message": "Invalid or expired reset token"
}
Xác thực mật khẩu hiện tại mà không thay đổi nó.
Yêu cầu:
{
"password": "currentpassword"
}
Xác minh email qua liên kết xác minh. Được gọi khi người dùng nhấp vào liên kết trong email.
Truy vấn: ?token=abc123&callbackURL=http://localhost:3000
Gửi email xác minh cho người dùng hiện tại.
Yêu cầu:
{
"email": "[email protected]",
"callbackURL": "http://localhost:3000/verified"
}
Thay đổi email người dùng (gửi xác minh đến email mới).
Yêu cầu:
{
"newEmail": "[email protected]"
}
Cập nhật hồ sơ người dùng hiện tại.
Yêu cầu:
{
"name": "John Updated",
"image": "https://example.com/avatar.jpg"
}
Yêu cầu xóa tài khoản. Gửi email xác nhận.
Xác nhận xóa tài khoản qua liên kết email.
Lấy thông tin tài khoản hiện tại.
Liên kết tài khoản xã hội với người dùng hiện tại.
Yêu cầu:
{
"provider": "github",
"callbackURL": "http://localhost:3000/settings"
}
Hủy liên kết tài khoản xã hội khỏi người dùng hiện tại.
Yêu cầu:
{
"providerId": "github",
"accountId": "account-123"
}
Liệt kê tất cả các tài khoản đã liên kết của người dùng hiện tại.
Đầu nối kiểm tra sức khỏe.
Phản hồi 200: { "ok": true }
Đầu nối trang lỗi.
Tất cả đầu nối admin đều yêu cầu vai trò admin.
Liệt kê tất cả người dùng với phân trang.
Yêu cầu:
{
"limitValue": 20,
"offsetValue": 0
}
Lấy thông tin người dùng theo ID.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Tạo người dùng mới (admin). Đây là cách duy nhất để tạo tài khoản super_admin.
Yêu cầu:
{
"name": "Jane Doe",
"email": "[email protected]",
"password": "tempPassword123",
"role": "super_admin"
}
Tùy chọn Vai trò: user, super_admin
Cập nhật thông tin người dùng (admin).
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jane Updated",
"role": "super_admin"
}
Xóa vĩnh viễn người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Đặt vai trò hệ thống cho người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"role": "super_admin"
}
Tùy chọn Vai trò: user, super_admin
Khóa người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"banReason": "Violation of terms",
"banExpiresIn": 86400
}
Mở khóa người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Đăng nhập giả danh người dùng (phiên admin).
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Dừng đăng nhập giả danh và quay lại phiên admin.
Liệt kê tất cả các phiên của một người dùng cụ thể.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Thu hồi một phiên cụ thể của người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"sessionId": "session-123"
}
Thu hồi tất cả các phiên của người dùng.
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000"
}
Đặt mật khẩu cho người dùng (admin, không yêu cầu mật khẩu hiện tại).
Yêu cầu:
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"newPassword": "newpassword123"
}
Kiểm tra xem admin có một quyền cụ thể hay không.
Yêu cầu:
{
"permission": "user:delete"
}
Tạo tổ chức mới.
Yêu cầu:
{
"name": "Acme Corp",
"slug": "acme-corp",
"logo": "https://example.com/logo.png"
}
Cập nhật thông tin tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"name": "Acme Corporation"
}
Xóa tổ chức.
Yêu cầu:
{
"organizationId": "org-123"
}
Đặt tổ chức đang hoạt động cho phiên hiện tại.
Yêu cầu:
{
"organizationId": "org-123"
}
Lấy thông tin đầy đủ của tổ chức bao gồm thành viên, nhóm, lời mời.
Truy vấn: ?organizationId=org-123
Liệt kê tất cả các tổ chức của người dùng hiện tại.
Lấy thông tin thành viên của người dùng hiện tại trong tổ chức đang hoạt động.
Lấy vai trò của người dùng hiện tại trong tổ chức đang hoạt động.
Liệt kê tất cả thành viên của tổ chức đang hoạt động.
Truy vấn: ?organizationId=org-123&limitValue=20&offsetValue=0
Xóa thành viên khỏi tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"userId": "user-456"
}
Cập nhật vai trò của thành viên trong tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"userId": "user-456",
"role": "HR"
}
Rời khỏi tổ chức hiện tại.
Yêu cầu:
{
"organizationId": "org-123"
}
Kiểm tra xem slug tổ chức có khả dụng không.
Yêu cầu:
{
"slug": "acme-corp"
}
Liệt kê các lời mời đang chờ xử lý cho người dùng hiện tại.
Mời thành viên vào tổ chức. Tạo token bảo mật (băm SHA-256 được lưu trữ, token gốc gửi qua email).
Yêu cầu:
{
"organizationId": "org-123",
"email": "[email protected]",
"role": "HR",
"teamId": "team-789",
"employerId": "emp-456"
}
Các trường Yêu cầu:
| Trường | Loại | Bắt buộc | Mô tả |
|---|---|---|---|
| organizationId | string | Có | ID tổ chức đích |
| string | Có | Địa chỉ email người được mời | |
| role | string | Có | Vai trò tổ chức: HR, Candidate, Employer |
| teamId | string | Không | ID nhóm đích |
| employerId | string | Không | ID Employer (bắt buộc cho vai trò HR) |
Phản hồi 200:
{
"id": "inv-123",
"email": "[email protected]",
"role": "HR",
"status": "pending",
"expiresAt": "2026-08-12T10:30:00Z"
}
Lỗi 409 — Trùng lặp:
{
"message": "A pending invitation already exists for this email with the same role"
}
Lấy thông tin lời mời.
Truy vấn: ?id=inv-123
Liệt kê tất cả lời mời của tổ chức.
Truy vấn: ?organizationId=org-123
Chấp nhận lời mời.
Yêu cầu:
{
"invitationId": "inv-123"
}
Từ chối lời mời.
Yêu cầu:
{
"invitationId": "inv-123"
}
Hủy lời mời đang chờ xử lý.
Yêu cầu:
{
"invitationId": "inv-123"
}
Xác minh tính hợp lệ của token lời mời. Không yêu cầu xác thực. Được sử dụng bởi frontend khi người dùng nhấp vào liên kết lời mời từ email.
Truy vấn: ?token={raw_token}
Phản hồi 200 — Hợp lệ:
{
"valid": true,
"invitation": {
"id": "inv-123",
"email": "[email protected]",
"role": "HR",
"organizationId": "org-123",
"expiresAt": "2026-08-12T10:30:00Z"
}
}
Phản hồi 200 — Không hợp lệ (hết hạn):
{
"valid": false,
"reason": "expired"
}
Phản hồi 200 — Không hợp lệ (đã chấp nhận):
{
"valid": false,
"reason": "accepted"
}
Phản hồi 200 — Không hợp lệ (đã thu hồi):
{
"valid": false,
"reason": "revoked"
}
Lỗi 404 — Token không tìm thấy:
{
"message": "Invalid invitation token"
}
Gửi lại lời mời với token mới. Token trước đó bị vô hiệu hóa. Yêu cầu xác thực và là chủ sở hữu.
Yêu cầu:
{
"invitationId": "inv-123"
}
Phản hồi 200:
{
"id": "inv-123",
"email": "[email protected]",
"status": "pending",
"expiresAt": "2026-08-12T10:30:00Z",
"message": "Invitation resent successfully"
}
Lỗi 403 — Không phải chủ sở hữu:
{
"message": "Only the original inviter can resend this invitation"
}
Lỗi 409 — Đã chấp nhận:
{
"message": "Cannot resend an accepted invitation"
}
Thu hồi lời mời đang chờ xử lý. Chỉ người mời ban đầu mới có thể thu hồi. Lời mời đã chấp nhận hoặc đã thu hồi không thể thu hồi lại.
Yêu cầu:
{
"invitationId": "inv-123"
}
Phản hồi 200:
{
"message": "Invitation revoked successfully"
}
Lỗi 403 — Không phải chủ sở hữu:
{
"message": "Only the original inviter can revoke this invitation"
}
Lỗi 409 — Đã chấp nhận/đã thu hồi:
{
"message": "Cannot revoke an already accepted or revoked invitation"
}
Tạo nhóm trong tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"name": "Engineering"
}
Liệt kê tất cả các nhóm trong tổ chức.
Truy vấn: ?organizationId=org-123
Liệt kê các nhóm mà người dùng hiện tại thuộc về.
Cập nhật thông tin nhóm.
Yêu cầu:
{
"teamId": "team-789",
"name": "Engineering Team"
}
Xóa nhóm khỏi tổ chức.
Yêu cầu:
{
"teamId": "team-789"
}
Đặt nhóm đang hoạt động cho phiên hiện tại.
Yêu cầu:
{
"teamId": "team-789"
}
Liệt kê thành viên của một nhóm.
Truy vấn: ?teamId=team-789
Thêm thành viên vào nhóm.
Yêu cầu:
{
"teamId": "team-789",
"userId": "user-456"
}
Xóa thành viên khỏi nhóm.
Yêu cầu:
{
"teamId": "team-789",
"userId": "user-456"
}
Mỗi tổ chức có thể định nghĩa các vai trò riêng với quyền chi tiết được giới hạn trong phạm vi tổ chức đó. Các vai trò này độc lập với vai trò cấp hệ thống (user, super_admin).
Các Vai trò Tổ chức Tiêu chuẩn:
| Vai trò | Mô tả | Quyền thông thường |
|---|---|---|
Employer | Chủ sở hữu/quản trị viên tổ chức quản lý hồ sơ công ty và tin tuyển dụng | job:create, job:update, job:delete, application:read, member:read, settings:read, settings:update |
HR | Thành viên nhóm tuyển dụng nội bộ quản lý quy trình tuyển dụng | job:read, job:create, job:update, application:read, application:update, interview:create, interview:update, member:read |
Candidate | Người tìm việc ứng tuyển vào các vị trí trong tổ chức | job:read, application:create, application:read (chỉ của bản thân) |
Lưu ý: Khi người dùng tạo tổ chức, họ tự động nhận vai trò Employer trong tổ chức đó. Các vai trò bổ sung có thể được tạo qua POST /organization/create-role và gán cho thành viên qua lời mời hoặc POST /organization/update-member-role.
| Hành động | Được phép cho |
|---|---|
| Tạo vai trò | Chủ sở hữu hoặc quản trị viên tổ chức |
| Cập nhật vai trò | Chủ sở hữu hoặc quản trị viên tổ chức |
| Xóa vai trò | Chủ sở hữu hoặc quản trị viên tổ chức |
| Liệt kê vai trò | Tất cả thành viên tổ chức |
| Lấy vai trò | Tất cả thành viên tổ chức |
| Kiểm tra quyền | Tất cả người dùng đã xác thực |
Các quyền hợp lệ tuân theo định dạng resource:action. Nhiều quyền được ngăn cách bằng dấu phẩy.
| Quyền | Mô tả |
|---|---|
member:read | Xem thành viên tổ chức |
member:update | Cập nhật vai trò thành viên |
member:delete | Xóa thành viên khỏi tổ chức |
job:read | Xem tin tuyển dụng |
job:create | Tạo tin tuyển dụng mới |
job:update | Cập nhật tin tuyển dụng |
job:delete | Xóa tin tuyển dụng |
application:read | Xem đơn ứng tuyển |
application:update | Cập nhật trạng thái đơn ứng tuyển |
application:delete | Xóa đơn ứng tuyển |
interview:read | Xem phỏng vấn |
interview:create | Lên lịch phỏng vấn |
interview:update | Cập nhật thông tin phỏng vấn |
interview:delete | Hủy phỏng vấn |
report:read | Xem báo cáo và phân tích |
report:create | Tạo báo cáo |
settings:read | Xem cài đặt tổ chức |
settings:update | Cập nhật cài đặt tổ chức |
resource:actionTạo vai trò tùy chỉnh trong tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"role": "recruiter",
"description": "Can manage jobs and applications",
"permission": "job:read,job:create,job:update,application:read,application:update"
}
Cập nhật vai trò tổ chức.
Yêu cầu:
{
"organizationId": "org-123",
"roleId": "role-123",
"description": "Updated description",
"permission": "job:read,job:create,job:update,job:delete,application:read,application:update"
}
Xóa vai trò tùy chỉnh khỏi tổ chức. Không thể xóa nếu có thành viên đang được gán vai trò này.
Yêu cầu:
{
"organizationId": "org-123",
"roleId": "role-123"
}
Liệt kê tất cả vai trò trong tổ chức.
Truy vấn: ?organizationId=org-123
Phản hồi 200:
{
"roles": [
{
"id": "role-123",
"name": "recruiter",
"description": "Can manage jobs and applications",
"permissions": ["job:read", "job:create", "job:update", "application:read", "application:update"],
"memberCount": 5,
"createdAt": "2026-08-05T10:30:00Z"
}
]
}
Lấy thông tin vai trò.
Truy vấn: ?organizationId=org-123&roleId=role-123
Kiểm tra xem người dùng hiện tại có một quyền trong tổ chức hay không.
Yêu cầu:
{
"organizationId": "org-123",
"permission": "job:create"
}
Phản hồi 200:
{
"hasPermission": true
}
Lấy JSON Web Key Set để xác thực JWT.
Phản hồi 200:
{
"keys": [
{
"kty": "RSA",
"kid": "key-123",
"use": "sig",
"n": "...",
"e": "AQAB"
}
]
}
Lấy JWT token đã ký cho phiên hiện tại.
| Trạng thái HTTP | Mã Lỗi | Mô tả |
|---|---|---|
| 400 | VALIDATION_ERROR | Kiểm tra yêu cầu thất bại (tham số thiếu/không hợp lệ) |
| 401 | UNAUTHORIZED | Thiếu hoặc xác thực không hợp lệ |
| 401 | INVALID_CREDENTIALS | Sai email/số điện thoại hoặc mật khẩu |
| 401 | TOKEN_EXPIRED | JWT token đã hết hạn |
| 403 | FORBIDDEN | Không đủ quyền hạn |
| 404 | NOT_FOUND | Không tìm thấy tài nguyên |
| 409 | CONFLICT | Email hoặc số điện thoại đã được đăng ký; lời mời trùng lặp |
| 410 | INVITATION_EXPIRED | Token lời mời đã hết hạn |
| 429 | RATE_LIMITED | Quá nhiều yêu cầu |
| 500 | INTERNAL_ERROR | Lỗi máy chủ |