Files
immish/docs/login-flow.md

12 KiB

Authentication & Login

This document describes the authentication flow, login process, and session management.

Overview

The app supports two authentication methods:

  1. Email/Password Login - Traditional credentials
  2. OAuth Login - External identity provider (SSO)

Login Flow Diagram

┌─────────────────────────────────────────────────────────────────┐
│                        Splash Screen                             │
│  - Check for existing session                                    │
│  - Initialize databases                                          │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
    ┌─────────────────┐             ┌─────────────────┐
    │ Has Valid Token │             │  No Token/      │
    │                 │             │  Token Expired  │
    └─────────────────┘             └─────────────────┘
              │                               │
              ▼                               ▼
    ┌─────────────────┐             ┌─────────────────┐
    │   Main App      │             │   Login Page    │
    │   (Timeline)    │             │                 │
    └─────────────────┘             └─────────────────┘

Login Page UI

Screen Layout

┌─────────────────────────────────────┐
│                                     │
│            [Immich Logo]            │
│             (animated)              │
│                                     │
│            "immich" text            │
│                                     │
├─────────────────────────────────────┤
│  Server URL                         │
│  ┌─────────────────────────────┐    │
│  │ https://your-server.com     │    │
│  └─────────────────────────────┘    │
│                                     │
│         [Next Button]               │
│                                     │
│         [Settings]                  │
│                                     │
├─────────────────────────────────────┤
│    v1.2.3          Logs             │
└─────────────────────────────────────┘

After server validation:

┌─────────────────────────────────────┐
│                                     │
│            [Immich Logo]            │
│                                     │
│         server-url.com              │
│                                     │
├─────────────────────────────────────┤
│  Email                              │
│  ┌─────────────────────────────┐    │
│  │ user@example.com            │    │
│  └─────────────────────────────┘    │
│                                     │
│  Password                           │
│  ┌─────────────────────────────┐    │
│  │ ••••••••                    │    │
│  └─────────────────────────────┘    │
│                                     │
│         [Login Button]              │
│         ─────────────               │
│         [OAuth Button]              │
│                                     │
│         [Back]                      │
└─────────────────────────────────────┘

Server URL Validation

Process

  1. User enters server URL
  2. App sanitizes URL (adds https:// if missing, removes trailing slash)
  3. Attempts to resolve endpoint via /.well-known/immich
  4. Falls back to {url}/api if well-known not found
  5. Pings server to verify reachability
  6. Stores validated URL locally

Well-Known Discovery

GET {server_url}/.well-known/immich

Response:
{
  "api": {
    "endpoint": "/api"  // or absolute URL
  }
}

Server Info Fetch

After URL validation, fetch server configuration:

GET /server/config
GET /server/features

This determines:

  • Whether OAuth is enabled
  • Whether password login is enabled
  • OAuth button text
  • Server version (for compatibility check)

Email/Password Login

API Request

POST /auth/login

Headers:
  deviceModel: "iPhone 14 Pro" | "Pixel 7"
  deviceType: "iOS" | "Android"

Body:
{
  "email": "user@example.com",
  "password": "secret123"
}

Response:
{
  "accessToken": "eyJhbG...",
  "userId": "uuid-here",
  "userEmail": "user@example.com",
  "name": "John Doe",
  "isAdmin": false,
  "shouldChangePassword": false,
  "profileImagePath": "/path/to/image"
}

Post-Login Actions

  1. Store access token securely
  2. Store user info locally
  3. Generate/retrieve device ID
  4. Connect WebSocket for real-time updates
  5. Request gallery permissions
  6. Start initial sync
  7. Navigate to main app

OAuth Login (PKCE Flow)

Flow Diagram

┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│   App    │     │  Server  │     │   OAuth  │     │   App    │
│          │     │          │     │ Provider │     │          │
└────┬─────┘     └────┬─────┘     └────┬─────┘     └────┬─────┘
     │                │                │                │
     │ 1. Request     │                │                │
     │    OAuth URL   │                │                │
     │───────────────►│                │                │
     │                │                │                │
     │ 2. Return URL  │                │                │
     │    + state     │                │                │
     │◄───────────────│                │                │
     │                │                │                │
     │ 3. Open Browser with code_challenge              │
     │────────────────────────────────►│                │
     │                │                │                │
     │ 4. User authenticates           │                │
     │                │                │                │
     │ 5. Redirect with auth code      │                │
     │◄────────────────────────────────│                │
     │                │                │                │
     │ 6. Exchange code for token (with code_verifier)  │
     │───────────────►│                │                │
     │                │                │                │
     │ 7. Return access token          │                │
     │◄───────────────│                │                │

PKCE Parameters

  • code_verifier: Random 43-128 character string
  • code_challenge: SHA256 hash of verifier, base64url encoded
  • state: Random 32 character string for CSRF protection

OAuth Request

GET /oauth/authorize?
  code_challenge={code_challenge}&
  code_challenge_method=S256&
  state={state}

Response:
{
  "url": "https://oauth-provider.com/auth?client_id=..."
}

OAuth Callback

POST /oauth/callback

Body:
{
  "url": "immich://oauth-callback?code=xxx&state=yyy",
  "codeVerifier": "original_code_verifier"
}

Response:
{
  "accessToken": "eyJhbG...",
  "userId": "uuid-here",
  ...
}

Session Management

Access Token Storage

  • Stored in secure/encrypted storage
  • Token included in all API requests via header
  • Automatically loaded on app start

Request Authentication

All authenticated requests include:

Headers:
  Authorization: Bearer {access_token}
  x-immich-user-token: {access_token}  // alternative

Token Validation

On app start:

  1. Load stored token
  2. Call GET /users/me to validate
  3. If valid, proceed to app
  4. If invalid (401), redirect to login

Logout

Process

  1. Call server logout endpoint
  2. Clear local access token
  3. Clear user data from database
  4. Disable background backup
  5. Cancel ongoing sync operations
  6. Navigate to login screen

API Request

POST /auth/logout

Data Cleared on Logout

  • Access token
  • Current user info
  • Asset ETag (sync marker)
  • Auto endpoint switching settings
  • Preferred WiFi name
  • Local/external endpoint list

Password Change

If shouldChangePassword is true after login:

  1. Redirect to Change Password screen
  2. User enters new password
  3. Submit password change
PUT /auth/change-password

Body:
{
  "password": "newSecurePassword123"
}

Multi-Server Support

Automatic Endpoint Switching

The app can automatically switch between local and external server URLs based on WiFi network:

  1. Configure local endpoint (e.g., http://192.168.1.100:2283)
  2. Configure external endpoint (e.g., https://photos.example.com)
  3. Set preferred WiFi network name
  4. When on preferred WiFi, use local endpoint
  5. Otherwise, use external endpoint

Auxiliary Endpoint Validation

Before switching, validate the new endpoint is reachable:

GET {endpoint}/users/me

Response: 200 OK = valid endpoint

PIN Code / Local Auth

For the locked folder feature:

  • User can set up a PIN code
  • PIN is stored securely on device
  • Biometric authentication can be used as alternative

PIN Setup

PUT /auth/pin-code

Body:
{
  "pinCode": "1234"
}

PIN Verification

POST /auth/pin-code/verify

Body:
{
  "pinCode": "1234"
}

Error Handling

Common Login Errors

Error User Message Cause
Invalid URL "Invalid server URL" Malformed URL entered
Server unreachable "Server is not reachable" Network issue or wrong URL
SSL Error "SSL certificate error" Self-signed cert not trusted
Invalid credentials "Login failed" Wrong email/password
OAuth failed "OAuth login failed" OAuth flow interrupted
API exception Error message from server Server-side error

Validation Rules

  • URL: Must be valid URL with http/https scheme
  • Email: Must contain @, no leading/trailing spaces
  • Password: No specific validation (server handles it)

Version Compatibility

After connecting to server, check version compatibility:

  1. Get app version
  2. Get server version from /server/version
  3. Compare major/minor versions
  4. Show warning if mismatch detected

Previous: Project Structure | Next: Main Navigation