mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 23:34:10 +02:00
106 lines
3.5 KiB
Markdown
106 lines
3.5 KiB
Markdown
# Authentication
|
|
|
|
## User Registration
|
|
|
|
A new user creates an account on a server. The client sends credentials via REST,
|
|
the server hashes the password, issues JWT tokens, and the client stores the
|
|
refresh token for "Remember Me" sessions.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant UI as ConnectDialog
|
|
participant AO as AppOrchestrator
|
|
participant CM as ConnectionManager
|
|
participant API as ApiClient
|
|
participant Auth as AuthController
|
|
participant US as UserService
|
|
participant JWT as JwtTokenService
|
|
participant DB as SQLite
|
|
|
|
UI->>AO: ConnectDialogResult(IsRegister: true)
|
|
AO->>CM: ConnectAsync(dialogResult)
|
|
CM->>API: RegisterAsync(username, password)
|
|
API->>Auth: POST /api/auth/register
|
|
Auth->>US: RegisterUserAsync(username, password, displayName)
|
|
US->>US: Validate (regex, length, uniqueness)
|
|
US->>DB: INSERT User (BCrypt hash)
|
|
US-->>Auth: UserOperationResult.Success
|
|
Auth->>JWT: GenerateAccessToken(user)
|
|
JWT-->>Auth: (token, expiresAt) [15 min]
|
|
Auth->>JWT: GenerateRefreshToken()
|
|
JWT-->>Auth: Base64 random (64 bytes)
|
|
Auth->>DB: INSERT RefreshToken (SHA256 hash)
|
|
Auth-->>API: LoginResponse
|
|
API->>API: SetTokens() — store in memory + set Bearer header
|
|
API-->>CM: LoginResponse
|
|
CM->>CM: Wire OnTokensRefreshed for config persistence
|
|
CM->>CM: Continue to connection setup (see Connection Flow)
|
|
```
|
|
|
|
---
|
|
|
|
## User Login
|
|
|
|
Returning user authenticates with username/password or a saved refresh token.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant UI as ConnectDialog
|
|
participant CM as ConnectionManager
|
|
participant API as ApiClient
|
|
participant Auth as AuthController
|
|
participant US as UserService
|
|
participant DB as SQLite
|
|
|
|
alt Saved refresh token (Remember Me)
|
|
UI->>CM: ConnectDialogResult(SavedRefreshToken: "...")
|
|
CM->>API: LoginWithRefreshTokenAsync()
|
|
API->>Auth: POST /api/auth/refresh
|
|
Auth->>DB: Lookup token by SHA256 hash
|
|
Auth->>DB: Revoke old token, issue new pair
|
|
Auth-->>API: LoginResponse (rotated tokens)
|
|
else Username + Password
|
|
UI->>CM: ConnectDialogResult(IsRegister: false)
|
|
CM->>API: LoginAsync(username, password)
|
|
API->>Auth: POST /api/auth/login
|
|
Auth->>US: AuthenticateUserAsync(username, password)
|
|
US->>DB: Fetch user, BCrypt.Verify(password, hash)
|
|
US->>DB: Update LastSeenAt
|
|
US-->>Auth: UserOperationResult.Success
|
|
Auth-->>API: LoginResponse
|
|
end
|
|
API->>API: SetTokens()
|
|
```
|
|
|
|
---
|
|
|
|
## Token Refresh
|
|
|
|
Access tokens expire after 15 minutes. The client auto-refreshes transparently
|
|
before requests and on 401 responses. Refresh tokens are rotated on each use.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant SR as SignalR / HTTP Request
|
|
participant API as ApiClient
|
|
participant Auth as AuthController
|
|
participant DB as SQLite
|
|
participant Config as config.json
|
|
|
|
SR->>API: GetValidTokenAsync() or HTTP 401
|
|
API->>API: Token expires within 60s?
|
|
alt Proactive refresh (SignalR token provider)
|
|
API->>Auth: POST /api/auth/refresh (old refresh token)
|
|
else Reactive refresh (HTTP 401 retry)
|
|
API->>Auth: POST /api/auth/refresh (old refresh token)
|
|
end
|
|
Auth->>DB: Lookup by SHA256 hash
|
|
Auth->>DB: Revoke old refresh token
|
|
Auth->>DB: INSERT new RefreshToken
|
|
Auth-->>API: LoginResponse (new token pair)
|
|
API->>API: SetTokens() — update Bearer header
|
|
API-->>API: Fire OnTokensRefreshed event
|
|
API-->>Config: Persist new refresh token (if Remember Me)
|
|
API->>SR: Retry original request with new token
|
|
```
|