Files
ackify/compose.yml
Benjamin 68426bc882 feat: add PKCE support to OAuth2 flow for enhanced security
- Implement PKCE (Proof Key for Code Exchange) with S256 method
- Add crypto/pkce module with code verifier and challenge generation
- Modify OAuth flow to include code_challenge in authorization requests
- Update HandleCallback to validate code_verifier during token exchange
- Extend session lifetime from 7 to 30 days
- Add comprehensive unit tests for PKCE functions
- Maintain backward compatibility with fallback for non-PKCE sessions
- Add detailed logging for OAuth flow with PKCE tracking

PKCE enhances security by preventing authorization code interception
attacks, as recommended by OAuth 2.1 and OIDC standards.

feat: add encrypted refresh token storage with automatic cleanup

- Add oauth_sessions table for storing encrypted refresh tokens
- Implement AES-256-GCM encryption for refresh tokens using cookie secret
- Create OAuth session repository with full CRUD operations
- Add SessionWorker for automatic cleanup of expired sessions
- Configure cleanup to run every 24h for sessions older than 37 days
- Modify OAuth flow to store refresh tokens after successful authentication
- Track client IP and user agent for session security validation
- Link OAuth sessions to user sessions via session ID
- Add comprehensive encryption tests with security validations
- Integrate SessionWorker into server lifecycle with graceful shutdown

This enables persistent OAuth sessions with secure token storage,
reducing the need for frequent re-authentication from 7 to 30 days.
2025-10-26 02:32:10 +02:00

80 lines
2.6 KiB
YAML

## SPDX-License-Identifier: AGPL-3.0-or-later
name: ackify-ce
services:
ackify-migrate:
image: btouchard/ackify-ce
container_name: ackify-ce-migrate
environment:
ACKIFY_LOG_LEVEL: "${ACKIFY_LOG_LEVEL}"
ACKIFY_DB_DSN: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@ackify-db:5432/${POSTGRES_DB}?sslmode=disable"
depends_on:
ackify-db:
condition: service_healthy
networks:
- internal
command: ["/app/migrate", "up"]
entrypoint: []
restart: "no"
ackify-ce:
image: btouchard/ackify-ce
container_name: ackify-ce
restart: unless-stopped
environment:
ACKIFY_LOG_LEVEL: "${ACKIFY_LOG_LEVEL}"
ACKIFY_BASE_URL: "${ACKIFY_BASE_URL}"
ACKIFY_ORGANISATION: "${ACKIFY_ORGANISATION}"
ACKIFY_DB_DSN: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@ackify-db:5432/${POSTGRES_DB}?sslmode=disable"
ACKIFY_OAUTH_PROVIDER: "${ACKIFY_OAUTH_PROVIDER}"
ACKIFY_OAUTH_CLIENT_ID: "${ACKIFY_OAUTH_CLIENT_ID}"
ACKIFY_OAUTH_CLIENT_SECRET: "${ACKIFY_OAUTH_CLIENT_SECRET}"
ACKIFY_OAUTH_AUTH_URL: "${ACKIFY_OAUTH_AUTH_URL:-}"
ACKIFY_OAUTH_TOKEN_URL: "${ACKIFY_OAUTH_TOKEN_URL:-}"
ACKIFY_OAUTH_USERINFO_URL: "${ACKIFY_OAUTH_USERINFO_URL:-}"
ACKIFY_OAUTH_LOGOUT_URL: "${ACKIFY_OAUTH_LOGOUT_URL:-}"
ACKIFY_OAUTH_ALLOWED_DOMAIN: "${ACKIFY_OAUTH_ALLOWED_DOMAIN:-}"
ACKIFY_OAUTH_COOKIE_SECRET: "${ACKIFY_OAUTH_COOKIE_SECRET}"
ACKIFY_ED25519_PRIVATE_KEY: "${ACKIFY_ED25519_PRIVATE_KEY}"
ACKIFY_LISTEN_ADDR: ":8080"
ACKIFY_ADMIN_EMAILS: "${ACKIFY_ADMIN_EMAILS}"
ACKIFY_MAIL_HOST: "${ACKIFY_MAIL_HOST:-mailhog}"
ACKIFY_MAIL_PORT: "${ACKIFY_MAIL_PORT:-1025}"
ACKIFY_MAIL_TLS: "false"
ACKIFY_MAIL_STARTTLS: "false"
ACKIFY_MAIL_FROM: "${ACKIFY_MAIL_FROM:-noreply@ackify.local}"
ACKIFY_MAIL_FROM_NAME: "${ACKIFY_MAIL_FROM_NAME:-Ackify}"
depends_on:
ackify-migrate:
condition: service_completed_successfully
ackify-db:
condition: service_healthy
networks:
- internal
ports:
- "8080:8080"
ackify-db:
image: postgres:16-alpine
container_name: ackify-db
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- ackify_data:/var/lib/postgresql/data
networks:
- internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
networks:
internal:
volumes:
ackify_data: