User registration and login service. It uses PostgreSQL for storage and JWT for authentication tokens. For now only serves to survey-forms
- HTTP server built with
chi - PostgreSQL database with automatic schema initialization on startup
- JWT tokens with
email,user_id, androleclaims - Email-domain allowlist for registrations
- Password hashing with bcrypt
environment variables list
DATABASE_URL- PostgreSQL connection string. Must start withpostgres://orhost=PORT- HTTP listen address, for example:8081JWT_SECRET- HMAC secret used to sign and validate tokensJWT_ISSUER- expected JWT issuerJWT_AUDIENCE- expected JWT audienceALLOWED_EMAIL_DOMAINS- comma-separated list of allowed registration domains
Example .env values are provided in .env.example.
The repository includes docker-compose.yml for PostgreSQL only. It creates a users_service database with user users_app and password users_pass on port 5432.
docker compose up -dAll endpoints accept and return JSON unless noted otherwise.
GET /health- Returns
OK
POST /register- Body:
{
"email": "user@example.com",
"password": "strongPassword123"
}- Validation rules:
- Email must be valid and its domain must be listed in
ALLOWED_EMAIL_DOMAINS - Password must be 8 to 72 characters long
- Password must contain ASCII characters only
- Email must be valid and its domain must be listed in
Successful registration returns HTTP 200 with an empty body.
POST /login- Body:
{
"email": "user@example.com",
"password": "strongPassword123"
}- Response example:
{
"message": "logged in",
"token": "<jwt>",
"email": "user@example.com",
"user_id": "<uuid>",
"role": "user",
"expires": "2026-05-13T10:00:00Z"
}The token is valid for 12 hours and is signed with JWT_SECRET.
Send the JWT in the Authorization header when calling protected routes introduced in future revisions:
Authorization: Bearer <token>On startup the service creates the users table if it does not already exist. The table includes:
idas a UUID primary keyemailas a unique fieldpassword_hashfor bcrypt hashesrolewith a default value ofusercreated_attimestamp
main.go- application entrypoint and route setupinternal/config- environment loading and parsinginternal/handlers- HTTP handlers for login and registrationinternal/repository- PostgreSQL access and schema creationinternal/dto- request payload typesinternal/validations- email and password validation helpersinternal/models- domain model placeholderpkg/auth- JWT creation, validation, and password hashing
Run the test suite with:
go test ./...- The current HTTP surface only exposes
GET /health,POST /register, andPOST /login. main.goloads.envautomatically if present.- The service exits on startup if required configuration is missing.