# Authentication | EchoHub Documentation

# 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.

    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.

    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.

    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