ath fix
This commit is contained in:
+45
-10
@@ -18,7 +18,7 @@ Path-based versioning. Breaking changes bump the major version.
|
||||
```
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
- Every endpoint requires a valid **Bearer JWT**; unauthenticated → `401`. Tokens are issued by the **external AuthHex IdP** (not ERPCore) — **RS256**, issuer `AuthHex`, audience `AuthHexClient`. ERPCore validates them against AuthHex's static RSA public key (no JWKS) and admits only holders of the configured ERP `UserType`/`Role` (door policy) → otherwise `403`.
|
||||
- Every endpoint requires a valid **Bearer JWT**, sent either as an `Authorization: Bearer <token>` header or as the `erp_at` httpOnly cookie issued by `AuthController` (§2.0); unauthenticated → `401`. Tokens are issued by the **external AuthHex IdP** (not ERPCore) — **RS256**, issuer `AuthHex`, audience `AuthHexClient`. ERPCore validates them against AuthHex's static RSA public key (no JWKS) and admits only holders of the configured ERP `UserType`/`Role` (door policy) → otherwise `403`.
|
||||
- **Per-endpoint RBAC is NOT enforced in Phase 1** (FR-X-01): any ERP-admitted user may call any endpoint.
|
||||
- The **audit actor** is AuthHex's custom **`UserId` (GUID)** claim, mapped to a local shadow user (`int`). Clients never send `createdBy`; the server derives it (docs/10 A.4).
|
||||
|
||||
@@ -59,15 +59,50 @@ Domain errors add a stable `code` (catalog §7):
|
||||
|
||||
## 2. Master Data
|
||||
|
||||
### 2.0 Auth — **external (AuthHex IdP); not an ERPCore endpoint**
|
||||
> **Superseded (2026-07-14).** ERPCore no longer exposes `/auth/login`. Login, registration and recovery are owned by the
|
||||
> separate **AuthHex** service (e.g. `POST /api/loginUser` with `{ identifier, password }`), which returns an **RS256** JWT
|
||||
> (issuer `AuthHex`, audience `AuthHexClient`; claims `UserId` (GUID), `UserTypeCode`, `RoleCode`, `NIC`, …). ERPCore only
|
||||
> **validates** that Bearer token and provisions a local shadow user (docs/10 A.4). The old shape is retained here for history:
|
||||
```json
|
||||
POST {AuthHex}/api/loginUser → { "identifier": "…", "password": "••••••••" }
|
||||
// 200 → an RS256 access token (Bearer). Bad credentials → 401. Token → ERPCore Authorization: Bearer <token>.
|
||||
```
|
||||
### 2.0 Auth — **`AuthController`, proxying the external AuthHex IdP**
|
||||
> **Superseding note (2026-07-16).** Un-superseded: the frontend no longer calls AuthHex directly. All of the endpoints
|
||||
> below live on ERPCore under `/api/v1/auth/*` (`Controllers/AuthController.cs`), each forwarding to the matching AuthHex
|
||||
> `functionName` (see the project-root `API_REFERENCE.md` for AuthHex's own contract) via `IAuthHexClient`. Session-issuing
|
||||
> endpoints deliver AuthHex's access/refresh tokens as **httpOnly Secure cookies** (`erp_at`, `erp_rt`) plus a non-httpOnly
|
||||
> `XSRF-TOKEN` cookie (docs/02-SECURITY.md §B.2) — response bodies never contain raw tokens. Mutating, cookie-authenticated
|
||||
> requests must echo the CSRF cookie value in an `X-XSRF-TOKEN` header or receive `403 CSRF_TOKEN_MISMATCH`; Bearer-header
|
||||
> callers (Swagger, service-to-service) are exempt. The JWT bearer handler also accepts the `erp_at` cookie in place of an
|
||||
> `Authorization` header (docs/10 A.4 Auth proxy), so every other `/api/v1/*` controller keeps working unchanged either way.
|
||||
|
||||
| Route | AuthHex function | Auth |
|
||||
|---|---|---|
|
||||
| `POST /api/v1/auth/register` | registerUser | Anonymous |
|
||||
| `POST /api/v1/auth/login` | loginUser | Anonymous |
|
||||
| `POST /api/v1/auth/login/otp/verify` | VerifyOtpForLogin | Anonymous |
|
||||
| `POST /api/v1/auth/refresh-token` | refreshToken | Anonymous (reads `erp_rt` cookie) |
|
||||
| `GET /api/v1/auth/users/{userId}` | getUserDetails | Anonymous* |
|
||||
| `GET /api/v1/auth/sessions` | getUserSessions | Required |
|
||||
| `POST /api/v1/auth/status` | ChangeUserStatus | Required + CSRF |
|
||||
| `POST /api/v1/auth/lock` | LockUserAccount | Required + CSRF |
|
||||
| `POST /api/v1/auth/change-password` | ChangeUserPassword | Required + CSRF |
|
||||
| `POST /api/v1/auth/verify-password` | VerifyPassword | Required |
|
||||
| `POST /api/v1/auth/logout` | LogoutUser | Anonymous* |
|
||||
| `PUT /api/v1/auth/me` | UpdateUser | Required + CSRF |
|
||||
| `POST /api/v1/auth/2fa/initiate` | initiateTwoFASetup | Required + CSRF |
|
||||
| `POST /api/v1/auth/2fa/complete` | completeTwoFASetup | Required + CSRF |
|
||||
| `POST /api/v1/auth/2fa/verify` | verifyTwoFA | Required + CSRF |
|
||||
| `POST /api/v1/auth/2fa/disable` | disableTwoFA | Required + CSRF |
|
||||
| `GET /api/v1/auth/2fa/status` | getTwoFAStatus | Required |
|
||||
| `POST /api/v1/auth/recovery/forgot-password` | forgotPassword | Anonymous |
|
||||
| `POST /api/v1/auth/recovery/verify-otp` | verifyOTP | Anonymous |
|
||||
| `POST /api/v1/auth/recovery/reset-password` | resetPassword | Anonymous |
|
||||
| `POST /api/v1/auth/recovery/reset-password-token` | resetPasswordWithToken | Anonymous |
|
||||
| `POST /api/v1/auth/availability` | IsAvailable | Anonymous |
|
||||
| `POST /api/v1/auth/otp/send` | sendOtp | Anonymous |
|
||||
| `POST /api/v1/auth/otp/verify` | VerifyOTP (Alt) | Anonymous |
|
||||
|
||||
\* `getUserDetails` and `LogoutUser` are anonymous because AuthHex itself resolves them from the request payload rather
|
||||
than the bearer token — carried over from AuthHex's own design, not introduced by this proxy. Tracked as an accepted risk
|
||||
in docs/02-SECURITY.md Part A.
|
||||
|
||||
Request/response field shapes match AuthHex's own payloads one-for-one (project-root `API_REFERENCE.md` §3–§5), except
|
||||
session-issuing responses omit `AccessToken`/`RefreshToken` (cookie-delivered instead) and `refreshToken` is read from the
|
||||
`erp_rt` cookie rather than the request body.
|
||||
|
||||
### 2.1 Items
|
||||
#### `GET /items`
|
||||
|
||||
Reference in New Issue
Block a user