Skip to main content

Overview

The Auth models define data structures for authentication, login, token refresh, and session management. These models handle the authentication flow in the Rodando Passenger app.

Authentication Request Models

LoginPayload

Payload for user login requests.
id
string
User ID (alternative to email/phone)
email
string
User’s email address (required if phoneNumber not provided)
phoneNumber
string
User’s phone number (required if email not provided)
password
string
required
User’s password
location
Location
User’s current geographic location
appAudience
AppAudience
required
Application platform making the request. One of: 'driver_app', 'passenger_app', 'admin_panel', or 'api_client'
expectedUserType
UserType
required
Expected user type for validation. One of: 'passenger', 'driver', or 'admin'
export type AppAudience = 'driver_app' | 'passenger_app' | 'admin_panel' | 'api_client';

export interface LoginPayload {
  id?: string;
  email?: string;
  phoneNumber?: string;
  password: string;
  location?: Location;
  appAudience: AppAudience;
  expectedUserType: UserType;
}
Either email or phoneNumber must be provided, but not both.

Authentication Response Models

BaseAuthResponse

Base interface containing common fields returned by login and refresh endpoints.
accessToken
string
required
JWT access token for authenticating API requests
accessTokenExpiresAt
number
required
Access token expiration time in epoch milliseconds
refreshTokenExpiresAt
number
Refresh token expiration time in epoch milliseconds
sid
string
Session ID (JWT token identifier). Primarily present in refresh responses
sessionType
SessionType
required
Type of session created. One of: 'web', 'mobile_app', 'admin_panel', or 'api_client'
export interface BaseAuthResponse {
  accessToken: string;
  accessTokenExpiresAt: number;
  refreshTokenExpiresAt?: number;
  sid?: string;
  sessionType: SessionType;
}

LoginResponseMobile

Login response for mobile applications. Includes refresh token in response body.
refreshToken
string
required
JWT refresh token (included in body for mobile apps)
Extends all fields from BaseAuthResponse.
export interface LoginResponseMobile extends BaseAuthResponse {
  refreshToken: string;
}

LoginResponseWeb

Login response for web applications. Refresh token sent via HTTP-only cookie.
refreshToken
never
Refresh token is NOT included in body for web (sent as HTTP-only cookie)
Extends all fields from BaseAuthResponse.
export interface LoginResponseWeb extends BaseAuthResponse {
  refreshToken?: never;
}

LoginResponse

Unified type for login responses across platforms.
export type LoginResponse = LoginResponseMobile | LoginResponseWeb;

RefreshResponseMobile

Token refresh response for mobile applications.
refreshToken
string
required
New refresh token (included in body for mobile apps)
Extends all fields from BaseAuthResponse.
export interface RefreshResponseMobile extends BaseAuthResponse {
  refreshToken: string;
}

RefreshResponseWeb

Token refresh response for web applications.
refreshToken
never
Refresh token is NOT included in body for web (sent as HTTP-only cookie)
Extends all fields from BaseAuthResponse.
export interface RefreshResponseWeb extends BaseAuthResponse {
  refreshToken?: never;
}

RefreshResponse

Unified type for refresh responses across platforms.
export type RefreshResponse = RefreshResponseMobile | RefreshResponseWeb;

Session and Device Models

SessionType

Enum defining available session types.
export enum SessionType {
  WEB = 'web',
  MOBILE_APP = 'mobile_app',
  ADMIN_PANEL = 'admin_panel',
  API_CLIENT = 'api_client',
}
Values:
  • WEB - Web browser session
  • MOBILE_APP - Mobile application session
  • ADMIN_PANEL - Admin panel session
  • API_CLIENT - API client session

DeviceInfo

Information about the client device.
os
string
Operating system (e.g., ‘iOS’, ‘Android’, ‘Windows’)
browser
string
Browser name and version
model
string
Device model
appVersion
string
Application version
export interface DeviceInfo {
  os?: string;
  browser?: string;
  model?: string;
  appVersion?: string;
}

Location

Geographic location information.
latitude
number
required
Latitude coordinate
longitude
number
required
Longitude coordinate
city
string
City name
country
string
Country name
export interface Location {
  latitude: number;
  longitude: number;
  city?: string;
  country?: string;
}

Error Models

ApiError

Standard error structure for API responses.
status
number
HTTP status code
message
string
required
Error message
code
string
Application-specific error code
validation
Record<string, string[]>
Validation errors by field nameExample: { "email": ["Email is required", "Invalid email format"] }
raw
any
Raw error data from the server
url
string | null
URL that caused the error
export interface ApiError {
  status?: number;
  message: string;
  code?: string;
  validation?: Record<string, string[]>;
  raw?: any;
  url?: string | null;
}

Supporting Types

ApiResponse

Generic wrapper for all API responses.
success
boolean
required
Whether the request was successful
message
string
required
Response message
data
T
required
Response data (generic type)
error
ApiError
Error details if request failed
meta
PaginationMeta
Pagination metadata for list responses
export interface ApiResponse<T> {
  success: boolean;
  message: string;
  data: T;
  error?: ApiError;
  meta?: PaginationMeta;
}

PaginationMeta

Pagination information for list responses.
page
number
Current page number (1-based)
limit
number
Items per page
total
number
Total number of items
totalPages
number
Total number of pages
export interface PaginationMeta {
  page?: number;
  limit?: number;
  total?: number;
  totalPages?: number;
}

Usage Examples

Login (Mobile App)

import { LoginPayload, LoginResponseMobile, SessionType } from '@/app/core/models/auth';
import { UserType } from '@/app/core/models/user/user.auxiliary';
import { HttpClient } from '@angular/common/http';
import { ApiResponse } from '@/app/core/models/api';

const loginData: LoginPayload = {
  email: '[email protected]',
  password: 'SecurePassword123!',
  appAudience: 'passenger_app',
  expectedUserType: UserType.Passenger,
  location: {
    latitude: 23.1136,
    longitude: -82.3666,
    city: 'La Habana',
    country: 'Cuba'
  }
};

this.http.post<ApiResponse<LoginResponseMobile>>('/auth/login', loginData)
  .subscribe(response => {
    if (response.success) {
      const { accessToken, refreshToken, sessionType } = response.data;
      
      // Store tokens securely
      localStorage.setItem('accessToken', accessToken);
      localStorage.setItem('refreshToken', refreshToken);
      
      console.log('Session type:', sessionType); // 'mobile_app'
    }
  });

Login with Phone Number

const loginData: LoginPayload = {
  phoneNumber: '+53 5555 1234',
  password: 'MyPassword456!',
  appAudience: 'passenger_app',
  expectedUserType: UserType.Passenger
};

Token Refresh (Mobile)

import { RefreshResponseMobile } from '@/app/core/models/auth/auth.response';

const refreshToken = localStorage.getItem('refreshToken');

this.http.post<ApiResponse<RefreshResponseMobile>>('/auth/refresh', 
  { refreshToken }
).subscribe(response => {
  if (response.success) {
    const { accessToken, refreshToken: newRefreshToken, sid } = response.data;
    
    // Update stored tokens
    localStorage.setItem('accessToken', accessToken);
    localStorage.setItem('refreshToken', newRefreshToken);
    
    console.log('Session ID:', sid);
  }
});

Handling Authentication Errors

import { ApiError } from '@/app/core/models/api';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

this.http.post<ApiResponse<LoginResponseMobile>>('/auth/login', loginData)
  .pipe(
    catchError((error) => {
      const apiError: ApiError = {
        status: error.status,
        message: error.error?.message || 'Login failed',
        code: error.error?.code,
        validation: error.error?.validation,
        url: error.url
      };
      
      if (apiError.validation) {
        // Handle validation errors
        Object.keys(apiError.validation).forEach(field => {
          console.error(`${field}:`, apiError.validation![field].join(', '));
        });
      }
      
      return throwError(() => apiError);
    })
  )
  .subscribe({
    next: (response) => console.log('Login successful'),
    error: (error: ApiError) => console.error('Login error:', error.message)
  });

Checking Token Expiration

import { LoginResponseMobile } from '@/app/core/models/auth/auth.response';

function isTokenExpired(response: LoginResponseMobile): boolean {
  const now = Date.now();
  return now >= response.accessTokenExpiresAt;
}

function shouldRefreshToken(response: LoginResponseMobile): boolean {
  const now = Date.now();
  const fiveMinutes = 5 * 60 * 1000;
  
  // Refresh if token expires in less than 5 minutes
  return (response.accessTokenExpiresAt - now) < fiveMinutes;
}

Session Type Handling

import { SessionType } from '@/app/core/models/auth/auth.auxiliary';

function getSessionStorageKey(sessionType: SessionType): string {
  switch (sessionType) {
    case SessionType.MOBILE_APP:
      return 'mobile_session';
    case SessionType.WEB:
      return 'web_session';
    case SessionType.ADMIN_PANEL:
      return 'admin_session';
    default:
      return 'api_session';
  }
}

Authentication Flow

Typical authentication flow in the Rodando Passenger app:
  1. User Login: Send LoginPayload to /auth/login
  2. Receive Tokens: Get LoginResponseMobile with access and refresh tokens
  3. Store Tokens: Securely store both tokens (use secure storage on mobile)
  4. Use Access Token: Include in Authorization header for API requests
  5. Monitor Expiration: Check accessTokenExpiresAt before requests
  6. Refresh When Needed: Use refresh token to get new access token
  7. Update Tokens: Replace old tokens with new ones from refresh response
// Authorization header format
const headers = {
  'Authorization': `Bearer ${accessToken}`
};

Security Best Practices

  • Never log or expose tokens in production
  • Use secure storage for tokens on mobile devices
  • Always use HTTPS for authentication requests
  • Implement automatic token refresh before expiration
  • Clear tokens on logout
  • Validate expectedUserType matches actual user type

Build docs developers (and LLMs) love