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 OKwith admin user data - Set cookies in response
- Include user details with role information
- Success:
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 Unauthorizedwith 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