Admin Login

Overview Description

The Admin Login feature provides authentication specifically for administrative users with elevated privileges. It follows a similar flow to the standard user login but includes additional checks for admin role verification and expanded user loading. This feature ensures that only users with proper admin permissions can access the administrative sections of the application, creating a clear separation between regular user access and administrative capabilities.

Activity Diagram

---
config:
  theme: base
  layout: dagre
  flowchart:
    curve: linear
    htmlLabels: true
  themeVariables:
    edgeLabelBackground: "transparent"
---
flowchart TD
    %% Main components
    AdminUser[Admin User]
    FirebaseService[Firebase Authentication]
    Database[(Database)]
    
    %% Process steps with numbering
    AdminUser --- Step1[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>1</span>
            <p style='margin-top: 8px'>Submit Login</p>
        </div>
    ]
    Step1 --> ValidateRequest[Validate Request]
    
    ValidateRequest --- Step2[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>2</span>
            <p style='margin-top: 8px'>Extract Token</p>
        </div>
    ]
    Step2 --> ExtractToken[Extract Firebase Token]
    
    ExtractToken --- Step3[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>3</span>
            <p style='margin-top: 8px'>Send to Auth Service</p>
        </div>
    ]
    Step3 --> AuthService[Auth Service]
    
    AuthService --- Step4[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>4</span>
            <p style='margin-top: 8px'>Verify Token</p>
        </div>
    ]
    Step4 --> FirebaseService
    
    FirebaseService --- Step5[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>5</span>
            <p style='margin-top: 8px'>Token Validation</p>
        </div>
    ]
    Step5 --> TokenCheck{Valid Token?}
    
    TokenCheck --- Step6A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6A</span>
            <p style='margin-top: 8px'>Return Error</p>
        </div>
    ]
    Step6A -->|No| ReturnError[Return Error]
    
    TokenCheck --- Step6B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>6B</span>
            <p style='margin-top: 8px'>Find User</p>
        </div>
    ]
    Step6B -->|Yes| FindUser[Find User in Database]
    
    FindUser --- Step7[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>7</span>
            <p style='margin-top: 8px'>Check Existence</p>
        </div>
    ]
    Step7 --> UserCheck{User Exists?}
    
    UserCheck --- Step8A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8A</span>
            <p style='margin-top: 8px'>Return Error</p>
        </div>
    ]
    Step8A -->|No| ReturnError
    
    UserCheck --- Step8B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>8B</span>
            <p style='margin-top: 8px'>Check Role</p>
        </div>
    ]
    Step8B -->|Yes| CheckAdminRole[Check Admin Role]
    
    CheckAdminRole --- Step9[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #6699cc !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>9</span>
            <p style='margin-top: 8px'>Validate Role</p>
        </div>
    ]
    Step9 --> RoleCheck{Has Admin Role?}
    
    RoleCheck --- Step10A[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #cc6666 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>10A</span>
            <p style='margin-top: 8px'>Return Error</p>
        </div>
    ]
    Step10A -->|No| ReturnError
    
    RoleCheck --- Step10B[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>10B</span>
            <p style='margin-top: 8px'>Generate Cookies</p>
        </div>
    ]
    Step10B -->|Yes| GenerateCookies[Generate Auth Cookies]
    
    GenerateCookies --- Step11[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>11</span>
            <p style='margin-top: 8px'>Return Data</p>
        </div>
    ]
    Step11 --> ReturnUserData[Return Admin User Data]
    
    ReturnUserData --- Step12[
        <div style='text-align: center'>
            <span style='display: inline-block; background-color: #99cc66 !important; color:white; width: 28px; height: 28px; line-height: 28px; border-radius: 50%; font-weight: bold'>12</span>
            <p style='margin-top: 8px'>Complete Login</p>
        </div>
    ]
    Step12 --> AdminUser
    
    %% Styling
    style AdminUser fill:#e6f3ff,stroke:#0066cc,stroke-width:2px
    style ValidateRequest fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ExtractToken fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style AuthService fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style FirebaseService fill:#fcd9d9,stroke:#cc3333,stroke-width:2px
    style TokenCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style FindUser fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style UserCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style CheckAdminRole fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style RoleCheck fill:#f5f0ff,stroke:#9966cc,stroke-width:2px
    style GenerateCookies fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ReturnUserData fill:#f0f8e6,stroke:#339933,stroke-width:2px
    style ReturnError fill:#fcd9d9,stroke:#cc3333,stroke-width:2px
    style Database fill:#ffe6cc,stroke:#ff9900,stroke-width:2px
    
    style Step1 fill:transparent,stroke:transparent,stroke-width:1px
    style Step2 fill:transparent,stroke:transparent,stroke-width:1px
    style Step3 fill:transparent,stroke:transparent,stroke-width:1px
    style Step4 fill:transparent,stroke:transparent,stroke-width:1px
    style Step5 fill:transparent,stroke:transparent,stroke-width:1px
    style Step6A fill:transparent,stroke:transparent,stroke-width:1px
    style Step6B fill:transparent,stroke:transparent,stroke-width:1px
    style Step7 fill:transparent,stroke:transparent,stroke-width:1px
    style Step8A fill:transparent,stroke:transparent,stroke-width:1px
    style Step8B fill:transparent,stroke:transparent,stroke-width:1px
    style Step9 fill:transparent,stroke:transparent,stroke-width:1px
    style Step10A fill:transparent,stroke:transparent,stroke-width:1px
    style Step10B fill:transparent,stroke:transparent,stroke-width:1px
    style Step11 fill:transparent,stroke:transparent,stroke-width:1px
    style Step12 fill:transparent,stroke:transparent,stroke-width:1px

API: Admin Login API

Case Documentation

Case 1: Successful Admin Login

Description

Administrator successfully logs in with valid credentials and admin role.

Sequence Diagram

sequenceDiagram
    participant Admin
    participant API as LoginController
    participant Service as AuthService
    participant Firebase
    participant DB as Database

    Note over Admin,API: Step 1: Submit Login
    Admin->>API: POST /api/v1/admin/auth/login (with firebase-token)
    
    Note over API,Service: Step 2: Process Login
    API->>Service: login(token, data)
    
    Note over Service,Firebase: Step 3: Verify Token
    Service->>Firebase: verifyIdToken(token)
    Firebase-->>Service: Return verified user info
    
    Note over Service,DB: Step 4: Find User
    Service->>DB: findByUid(uid)
    DB-->>Service: Return user data
    
    Note over Service,DB: Step 5: Check Admin Role
    Service->>DB: Check Admin Role 
    DB-->>Service: Return role data
    
    Note over Service,DB: Step 6: Load Group Data
    Service->>DB: Load group data
    DB-->>Service: Return group data
    
    Note over Service,DB: Step 7: Load Group Member
    Service->>DB: Load group member
    DB-->>Service: Return group member data
    
    Note over Service,DB: Step 8: Load Group Role
    Service->>DB: Load group role
    DB-->>Service: Return group role data
    
    Note over Service,API: Step 9: Generate Auth Cookie
    Service->>Service: createAuthCookie(user)
    
    Note over API,Admin: Step 10: Return Response
    API-->>Admin: 200 OK with user data and cookies

Steps

Step 1: Submit Login Request

  • Description: Admin sends login request with Firebase token
  • Request: POST /api/v1/admin/auth/login
  • Headers:
    • firebase-token: Firebase authentication token
  • Validation:
    • Token presence check
    • Token format validation

Step 2: Process Login

  • Description: Controller validates request and passes to service
  • Action:
    • Extract token from header
    • Call authentication service

Step 3: Verify Token

  • Description: Verify Firebase token authenticity
  • Action:
    • Send token to Firebase for verification
    • Extract user identifier from verified token

Step 4: Find User

  • Description: Locate user record and verify admin rights
  • Action:
    • Query database for user with matching Firebase UID
    • Load user's admin roles relationship
    • Check if user has any admin role assigned

Step 5: Check Admin Role

  • Description: Ensure user has appropriate admin permissions
  • Action:
    • Verify admin role exists and is valid
    • Check if specific role permissions are required

Step 6: Load Group Data

  • Description: Load group data related to the user
  • Action:
    • Query group database for user's group membership
    • Load group data related to each group

Step 7: Load Group Member

  • Description: Load group member data related to the user
  • Action:
    • Query group member database for user's membership details
    • Load group member data related to each group

Step 8: Load Group Role

  • Description: Load group role data related to the user
  • Action:
    • Query group role database for user's role in each group
    • Load group role data related to each group

Step 9: Generate Auth Cookie

  • Description: Create secure admin session cookie
  • Action:
    • Generate authentication token
    • Create auth cookie with token: Trend-Viewer_auth_api_token
    • Create logged-in state cookie: Trend-Viewer_is_logged_in

Step 10: Return Response

  • Description: Send successful response to client
  • Response:
    • Success: 200 OK with admin user data
    • Set cookies in response
    • Include user details with role information

Database Related Tables & Fields

erDiagram
    users {
        id bigint "Primary key"
        name string "User's full name"
        email string "User's email address (unique)"
        uid string "Firebase UID"
        status int "Account status"
        is_first_login boolean "Flag indicating if user has completed first login"
        payment_provider_customer_id string "Payment provider customer ID"
        show_free_plan_modal boolean "Show free plan modal flag"
        group_id bigint "Reference to groups table"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    groups {
        id bigint "Primary key"
        name string "Group name"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    group_members {
        id bigint "Primary key"
        user_id bigint "Reference to users table"
        group_id bigint "Reference to groups table"
        group_role_id bigint "Reference to group_roles table"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    group_roles {
        id bigint "Primary key"
        name string "Role name"
        slug string "Role slug"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    admin_roles {
        id bigint "Primary key"
        name string "Role name"
        slug string "Role slug"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }
    admin_role_user {
        user_id bigint "Reference to users table"
        admin_role_id bigint "Reference to admin_roles table"
        created_at timestamp "Record creation timestamp"
        updated_at timestamp "Record last update timestamp"
    }

    users ||--o{ group_members : has
    groups ||--o{ group_members : has
    group_roles ||--o{ group_members : has
    users ||--o{ admin_role_user : has
    admin_roles ||--o{ admin_role_user : has

Error Handling

  • Log

    • Login failures logged to application logs
    • Role verification errors recorded
    • (Optional) Send slack message for security events
  • Error Detail:

    Status Code Error Message Description
    401 "ログイン情報が正しくありません。" When user is not found in admin role
    401 "認証情報と一致するレコードがありません。" When login fails
    401 "問題が発生しました。申し訳ございませんが、もう一度お試しください。" When unexpected errors occur

Case 2: Failed Admin Login (No Admin Role)

Description

User with valid credentials attempts to login but does not have admin role.

Sequence Diagram

sequenceDiagram
    participant User
    participant API as AdminLoginController
    participant Service as AuthService
    participant Firebase
    participant DB as Database

    User->>API: POST /api/v1/admin/auth/login (with firebase-token)
    API->>Service: login(token, data)
    Service->>Firebase: verifyIdToken(token)
    Firebase-->>Service: Return verified token data
    Service->>DB: findByUid(firebase_uid)
    DB-->>Service: Return user data
    Service->>DB: Load admin roles
    DB-->>Service: Return empty roles
    Service-->>API: Return authInfo with user
    API->>API: Check user has admin role
    API-->>User: 401 Unauthorized (No admin role)

Steps

Step 1: Submit Login Request

  • Description: User sends login request with valid Firebase token
  • Request: Same as successful flow

Step 2: Token Verification Success

  • Description: Firebase verifies token and user is found
  • Action: Same as successful flow until role check

Step 3: Admin Role Check Failure

  • Description: System checks for admin role but none found
  • Action:
    • Check for adminRole relationship
    • Determine user lacks necessary permissions

Step 4: Error Response

  • Description: Return appropriate error to user
  • Response: 401 Unauthorized with error message about permissions

Additional Notes

  • Admin login shares authentication infrastructure with regular user login
  • Admin role check is an additional layer not present in regular login
  • Role-based access control determines available functionality after login
  • Admin users may have multiple roles with different permission levels
  • Admin sessions have the same security properties as regular user sessions