Backend Spec: User Authentication & Session Management (auth.login)
Estado de fase (MASTER-00): POST_MVP — documento de catálogo de producto sujeto a validación; no es alcance aprobado de Gate 0 / PoC / MVP. Gobernanza: MASTER-00.
Backend Spec: User Authentication & Session Management (auth.login)
Sección titulada «Backend Spec: User Authentication & Session Management (auth.login)»1. Overview & Objectives
Sección titulada «1. Overview & Objectives»This specification details the server-side implementation for user authentication (loginUser) in the :docugraph-backend Ktor service. It receives HTTP POST /api/v1/auth/login, validates user credentials against the PostgreSQL users table using Argon2id password hashing, retrieves subscription entitlement status from subscriptions, and issues an RS256-signed JWT access token alongside a refresh token.
2. API Endpoint Signature & Traceability
Sección titulada «2. API Endpoint Signature & Traceability»- HTTP Method & Path:
POST /api/v1/auth/login - operationId:
loginUser - Upstream Requirements:
US-01,IX-01,SCHEMA-01 - Primary Service Class:
AuthService.kt - Ktor Route Handler:
AuthRoutes.kt
3. Data Models & Kotlin Data Classes
Sección titulada «3. Data Models & Kotlin Data Classes»package io.docugraph.backend.models.auth
import kotlinx.serialization.Serializable
@Serializabledata class LoginRequest( val email: String, val password: String)
@Serializabledata class UserProfileDto( val id: String, val email: String, val fullName: String?)
@Serializabledata class AuthTokenResponse( val accessToken: String, val refreshToken: String, val tokenType: String = "Bearer", val expiresIn: Long = 900L, // 15 minutes in seconds val entitlementId: String, // "free" | "pro_tier" val user: UserProfileDto)4. Sequence & Control Flow
Sección titulada «4. Sequence & Control Flow»Client (FE-01) Ktor AuthRoute AuthService PostgreSQL DB | | | | |-- POST /auth/login -->| | | | (email, password) |-- validate(input) -->| | | | |-- SELECT FROM users->| | | |<- user record -------| | | | | | | |-- verify Argon2id -->| | | | | | | |-- SELECT sub --------| | | |<- entitlement -------| | | | | | | |-- generate JWTs ----->| |<- 200 OK TokenResp ---|<- AuthTokenResponse -| |5. Database Interaction & SQL Queries
Sección titulada «5. Database Interaction & SQL Queries»5.1 User Retrieval by Email
Sección titulada «5.1 User Retrieval by Email»SELECT id, email, password_hash, full_name, oauth_provider, created_at, updated_atFROM usersWHERE email = :emailLIMIT 1;5.2 Entitlement Lookup
Sección titulada «5.2 Entitlement Lookup»SELECT id, entitlement_id, status, offline_grace_untilFROM subscriptionsWHERE user_id = :userIdLIMIT 1;6. Password Verification & Token Generation Logic
Sección titulada «6. Password Verification & Token Generation Logic»- Argon2id Verification:
- Verification parameters: Memory 64MB, Iterations 3, Parallelism 4.
- Using
de.mkammerer.argon2.Argon2Factory:val argon2 = Argon2Factory.create()val isValid = argon2.verify(userRecord.passwordHash, request.password.toCharArray())if (!isValid) throw InvalidCredentialsException()
- JWT Payload Construction (RS256):
- Claims included:
sub(user_id),email,entitlement(freeorpro_tier),iss(“docugraph-auth”),iat,exp(15 mins from now).
- Claims included:
7. Error Handling & HTTP Status Codes
Sección titulada «7. Error Handling & HTTP Status Codes»| Error Condition | HTTP Code | Internal Code | Response Message |
|---|---|---|---|
| Invalid email format or blank password | 422 Unprocessable | INVALID_INPUT |
“Email must be valid and password cannot be empty.” |
| Email not found or password mismatch | 401 Unauthorized | INVALID_CREDENTIALS |
“The provided email or password is incorrect.” |
| User account disabled / suspended | 403 Forbidden | ACCOUNT_SUSPENDED |
“Account suspended. Please contact support.” |
| Database exception or internal error | 500 Server Error | INTERNAL_SERVER_ERROR |
“An unexpected error occurred.” |
8. Verification & Test Plan
Sección titulada «8. Verification & Test Plan»- Unit Test: Test
AuthServiceTest.ktwith mocked repository for valid/invalid password. - Integration Test: Issue real HTTP POST call against Ktor test container and verify returned JWT signature with public key.