Tham chiếu API: Shell
Tài liệu này chi tiết tất cả các điểm cuối API RESTful của Shell — trung tâm định danh, thanh toán và điều phối cốt lõi.
Base path: Tất cả các endpoint đều có tiền tố
/api.
1. Xác thực — Công khai
Không yêu cầu xác thực.
GET /api/auth/providers
Liệt kê tất cả các nhà cung cấp OAuth đã kích hoạt.
Phản hồi: { "code": 200, "data": [{ "providerId": "google", "type": "oauth2" }] }
GET /api/auth/login
Lấy URL ủy quyền OAuth để chuyển hướng người dùng đến.
Query: ?provider=<providerId> (tùy chọn)
Phản hồi: { "code": 200, "data": { "loginUrl": "https://..." } }
GET /api/auth/callback
Xử lý callback OAuth. Xác thực code và state, tạo phiên, chuyển hướng đến ứng dụng.
Query: code, state (tùy chọn)
POST /api/auth/register
Đăng ký người dùng mới và tạo tổ chức của họ.
Body:
{
"email": "string",
"username": "string",
"password": "string (tối thiểu 8 ký tự)",
"firstName": "string",
"lastName": "string",
"plan": "HOBBY | PRO | ENTERPRISE"
}POST /api/auth/local-login
Đăng nhập bằng username/email và mật khẩu.
Body: { "usernameOrEmail": "string", "password": "string" }
Phản hồi:
{
"accessToken": "string",
"refreshToken": "string",
"expiresIn": 3600,
"tokenType": "Bearer",
"user": { "id": "uuid", "email": "string", "username": "string", "organizationId": "uuid" }
}POST /api/auth/refresh
Làm mới access token đã hết hạn bằng refresh token.
Body: { "refreshToken": "string" }
Phản hồi: { "accessToken": "string", "expiresIn": 3600 }
GET /api/.well-known/jwks.json
Endpoint JWKS của Shell. Các dịch vụ satellite dùng để xác minh JWT RS256 do Shell phát hành.
Phản hồi: { "keys": [...] }
2. Xác thực — Phiên & Trao đổi Token
Yêu cầu JWT.
POST /api/auth/exchange
Trao đổi Shell JWT lấy JWT giới hạn phạm vi cho dịch vụ. Được các dịch vụ satellite gọi sau khi nhận Shell token qua BroadcastChannel.
Body: { "service": "string" } (slug dịch vụ, ví dụ: "drive")
Phản hồi: { "accessToken": "string", "expiresIn": 3600, "service": "string" }
POST /api/auth/exchange-keycloak
Trao đổi Keycloak token lấy Shell JWT. Không yêu cầu xác thực. Dùng cho luồng SSO Keycloak.
Body: { "keycloakToken": "string", "serviceId": "string (tùy chọn)" }
Phản hồi: { "accessToken": "string", "expiresIn": 3600, "service": "string" }
POST /api/auth/exchange-for-service
Trao đổi Shell JWT lấy JWT dịch vụ từ xa qua gRPC gateway. Yêu cầu JWT.
Body: { "keycloakToken": "string", "serviceId": "string" }
Phản hồi: { "accessToken": "string", "tokenType": "Bearer", "expiresIn": 3600, "service": "string" }
GET /api/auth/logout
Thu hồi phiên hiện tại và đưa JWT vào danh sách đen.
Phản hồi: { "message": "Logged out successfully" }
3. Xác thực — Quản lý Tài khoản
Yêu cầu JWT.
GET /api/auth/me
Lấy hồ sơ người dùng hiện tại và ngữ cảnh tổ chức.
Phản hồi:
{
"id": "uuid",
"email": "string",
"username": "string",
"firstName": "string",
"lastName": "string",
"organizationId": "uuid",
"organization": { "id": "uuid", "name": "string", "slug": "string", "type": "string", "subscriptionPlan": "string" },
"preferences": {}
}PUT /api/auth/me/preferences
Cập nhật tùy chọn giao diện của người dùng hiện tại (giao diện, ngôn ngữ, v.v.).
Body: Record<string, unknown>
Phản hồi: Đối tượng preferences đã cập nhật.
POST /api/auth/change-password
Đổi mật khẩu của người dùng hiện tại.
Body: { "currentPassword": "string", "newPassword": "string (tối thiểu 8 ký tự)" }
Phản hồi: 204 No Content
POST /api/auth/request-password-reset
Yêu cầu email đặt lại mật khẩu.
Body: { "email": "string" }
Phản hồi: 204 No Content
POST /api/auth/confirm-password-reset
Hoàn tất đặt lại mật khẩu bằng token nhận qua email.
Body: { "token": "string", "newPassword": "string (tối thiểu 8 ký tự)" }
Phản hồi: 204 No Content
4. Người dùng
Yêu cầu JWT. Tất cả endpoint được kiểm soát bằng permission.
GET /api/users
Liệt kê người dùng. Yêu cầu quyền USERS_LIST.
Query: ?filter (chuỗi JSON lọc)
POST /api/users
Tạo người dùng mới trong tổ chức. Yêu cầu quyền USERS_WRITE.
Phản hồi: 201 Created
GET /api/users/:id
Lấy thông tin người dùng kèm vai trò đã gán. Yêu cầu quyền USERS_READ.
PUT /api/users/:id
Cập nhật thông tin người dùng. Yêu cầu quyền USERS_WRITE.
DELETE /api/users/:id
Xóa người dùng. Yêu cầu quyền USERS_DELETE.
Phản hồi: 204 No Content
GET /api/users/:id/roles
Lấy danh sách ID vai trò của người dùng. Yêu cầu quyền USERS_READ.
Phản hồi: ["uuid", ...]
POST /api/users/:id/roles
Gán một hoặc nhiều vai trò cho người dùng. Yêu cầu quyền USERS_WRITE.
Body: { "roleIds": ["uuid", ...] }
Phản hồi: 201 Created
DELETE /api/users/:id/roles/:roleId
Xóa vai trò khỏi người dùng. Yêu cầu quyền USERS_WRITE.
Phản hồi: 204 No Content
5. Tổ chức
Yêu cầu JWT. Kiểm soát bằng permission.
GET /api/organizations
Liệt kê tổ chức. Yêu cầu quyền ORGANIZATIONS_LIST.
GET /api/organizations/:id
Lấy thông tin tổ chức kèm danh sách người dùng. Yêu cầu quyền ORGANIZATIONS_READ.
PUT /api/organizations/:id
Cập nhật thông tin tổ chức. Yêu cầu quyền ORGANIZATIONS_WRITE.
Body: { "name"?: "string", "type"?: "string", "status"?: "string", "domain"?: "string" }
PUT /api/organizations/:id/subscription
Ghi đè gói cước của tổ chức (admin). Yêu cầu quyền SUBSCRIPTIONS_ADMIN.
Body: { "planCode": "string" }
Phản hồi: { "success": true }
6. Phân quyền (RBAC)
Yêu cầu JWT.
GET /api/roles
Liệt kê tất cả vai trò có sẵn trong tổ chức.
GET /api/permissions
Liệt kê tất cả mã quyền hạn trên tất cả ứng dụng đã đăng ký.
POST /api/roles/:id/permissions
Gán tập hợp quyền hạn cho một vai trò.
7. Gói cước & Thanh toán
Yêu cầu JWT. Ngữ cảnh tổ chức được trích xuất từ JWT.
GET /api/subscriptions/current
Lấy gói cước đang hoạt động của tổ chức.
GET /api/subscriptions/usage
Lấy mức sử dụng so với hạn mức của tất cả quota.
POST /api/subscriptions/upgrade
Tạo phiên Stripe Checkout để nâng cấp gói cước.
Body: { "planCode": "string", "interval": "monthly | yearly" }
Phản hồi: { "checkoutUrl": "string" }
POST /api/subscriptions/upgrade-direct
Nâng cấp trực tiếp bằng phương thức thanh toán đã lưu (không cần chuyển hướng).
Body: { "planCode": "string", "interval": "monthly | yearly", "paymentMethodId": "string" }
Phản hồi: { "success": true }
GET /api/subscriptions/portal
Lấy URL Stripe Customer Portal để quản lý hóa đơn và thẻ.
Query: ?returnUrl
Phản hồi: { "portalUrl": "string" }
POST /api/subscriptions/check-limit
Kiểm tra xem tổ chức đã đạt hạn mức sử dụng chưa.
Body: { "limitKey": "string" }
POST /api/subscriptions/consume
Tăng bộ đếm sử dụng lên 1.
Body: { "limitKey": "string" }
Phản hồi: { "success": true }
POST /api/subscriptions/payment-methods/setup
Tạo Stripe SetupIntent để lưu thẻ mới.
Phản hồi: { "clientSecret": "string" }
GET /api/subscriptions/payment-methods
Liệt kê tất cả phương thức thanh toán đã lưu của tổ chức.
DELETE /api/subscriptions/payment-methods/:paymentMethodId
Xóa phương thức thanh toán đã lưu.
Phản hồi: { "success": true }
PUT /api/subscriptions/payment-methods/:paymentMethodId/default
Đặt phương thức thanh toán làm mặc định.
Phản hồi: { "success": true }
POST /api/subscriptions/webhook
Xử lý Stripe webhook. Không yêu cầu xác thực — xác thực qua header stripe-signature.
8. Gói Sản phẩm
Yêu cầu JWT. Kiểm soát bằng permission.
GET /api/plans
Liệt kê tất cả gói cước. Yêu cầu quyền PLANS_LIST.
GET /api/plans/:id
Lấy chi tiết gói cước bao gồm ứng dụng và hạn mức. Yêu cầu quyền PLANS_READ.
POST /api/plans
Tạo gói cước mới (chỉ admin).
Body:
{
"code": "string",
"name": "string",
"tagline": "string (tùy chọn)",
"monthlyPrice": 0,
"yearlyPrice": 0,
"section": "individual | business",
"ctaLabel": "string",
"ctaLink": "string",
"features": [{ "label": "string", "included": true }],
"status": "active | hidden | deprecated",
"serviceIds": ["uuid"]
}Phản hồi: 201 Created
PUT /api/plans/:id
Cập nhật thông tin gói cước. Yêu cầu quyền PLANS_WRITE.
GET /api/plans/:id/limits
Lấy tất cả hạn mức quota của gói. Yêu cầu quyền PLANS_READ.
PUT /api/plans/:id/limits
Thiết lập hạn mức quota cho gói (chỉ admin).
Body: { "limits": [{ "limitKey": "string", "limitValue": 100, "period": "monthly" }] }
POST /api/plans/:id/sync-stripe
Đồng bộ giá gói cước lên Stripe (chỉ admin).
9. Ứng dụng / Danh mục Dịch vụ
Yêu cầu JWT. Chỉ admin.
GET /api/admin/apps
Liệt kê tất cả ứng dụng SCS đã đăng ký.
Query: ?filter (chuỗi JSON)
GET /api/admin/apps/:id
Lấy thông tin ứng dụng theo ID.
POST /api/admin/apps
Đăng ký ứng dụng mới với đầy đủ metadata.
Body: { "slug", "name", "type", "apiUrl", "uiUrl"?, "icon"?, "description"?, "category"?, "status"?, "metadata"? }
Phản hồi: 201 Created
POST /api/admin/apps/register-remote
Đăng ký ứng dụng chỉ bằng UI entry URL. Shell tự động lấy metadata từ remote.
Body: { "uiUrl": "string (URL)", "slug"?: "string" }
Phản hồi: 201 Created
PUT /api/admin/apps/:id
Cập nhật thông tin đăng ký ứng dụng.
DELETE /api/admin/apps/:id
Xóa ứng dụng khỏi danh mục.
Phản hồi: 204 No Content
10. Onboarding
POST /api/onboarding (Công khai)
Gửi yêu cầu onboarding doanh nghiệp B2B.
Body:
{
"orgName": "string",
"orgType": "string",
"contactEmail": "string",
"firstName": "string",
"lastName": "string",
"applicantEmail": "string",
"contactPhone": "string (tùy chọn)",
"companySize": 100,
"ssoInterest": true,
"subscriptionPlan": "string (tùy chọn)"
}Phản hồi: 201 Created
GET /api/onboarding
Liệt kê tất cả yêu cầu onboarding (admin). Yêu cầu quyền ONBOARDING_LIST.
GET /api/onboarding/:id
Lấy chi tiết yêu cầu onboarding. Yêu cầu quyền ONBOARDING_READ.
PUT /api/onboarding/:id/approve
Duyệt yêu cầu — tạo tổ chức và tài khoản admin. Yêu cầu quyền ONBOARDING_APPROVE.
PUT /api/onboarding/:id/reject
Từ chối yêu cầu onboarding. Yêu cầu quyền ONBOARDING_REJECT.
Body: { "reason": "string" }
11. Cấu hình (Khám phá Công khai)
GET /api/config/apps (Công khai)
Trả về danh sách ứng dụng đang hoạt động cho Shell Launchpad UI.
GET /api/config/plans (Công khai)
Trả về các gói cước đang hoạt động cho trang giá công khai.
GET /api/config (Chỉ Admin)
Trả về cấu hình hạ tầng nội bộ (Keycloak, MinIO, Redis).
12. Kiểm toán
GET /api/admin/audit
Lấy các bản ghi kiểm toán gần đây. Yêu cầu quyền USERS_LIST.
Query: ?limit (1–50, mặc định 20)
13. Cổng S2S (gRPC/Connect)
Kênh giao tiếp giữa các dịch vụ. Yêu cầu token với aud: "shell-rbac".
RbacService.CheckPermission
Xác minh xem người dùng (sub) có thể thực hiện hành động (act) trên tài nguyên (obj) không. Được các dịch vụ satellite gọi để kiểm tra quyền hạn mà không cần REST roundtrip.
14. Mã Lỗi Tiêu chuẩn
| Mã trạng thái | Mô tả |
|---|---|
401 Unauthorized | Thiếu hoặc JWT Shell không hợp lệ. |
403 Forbidden | Không đủ quyền RBAC cho hành động yêu cầu. |
404 Not Found | Người dùng, vai trò, tổ chức hoặc gói cước không tồn tại. |
409 Conflict | Email hoặc slug đã được sử dụng. |
429 Too Many Requests | Vượt quá giới hạn tốc độ. |
500 Server Error | Lỗi nhà cung cấp danh tính hoặc cơ sở dữ liệu. |