Overview
The AuthService handles all authentication operations including login, token refresh, logout, and fetching user profiles. It provides unified methods that work for both web (cookie-based) and mobile (token-based) authentication flows.
Location: src/app/core/services/http/auth.service.ts
Base Configuration
private readonly baseUrl = environment . apiUrl ;
All endpoints use the apiUrl from the environment configuration.
Methods
login()
Authenticates a user with email/phone and password.
login (
payload : LoginPayload ,
httpOptions ?: { withCredentials? : boolean }
): Observable < LoginResponse >
Login credentials and configuration Show LoginPayload properties
User’s email address (required if phoneNumber not provided)
User’s phone number (required if email not provided)
Target audience: 'driver_app' | 'passenger_app' | 'admin_panel' | 'api_client'
Expected user type: 'passenger' | 'driver' | 'admin'
Optional location data with latitude and longitude
Optional HTTP configuration Set to true for web flows to include cookies
Authentication response containing tokens Show LoginResponse properties
JWT access token for API requests
Refresh token (only for mobile sessions)
Access token expiration timestamp (epoch ms)
Refresh token expiration timestamp (epoch ms)
Session identifier (JWT jti)
Usage Example
import { AuthService } from '@/app/core/services/http/auth.service' ;
import { UserType } from '@/app/core/models/user/user.auxiliary' ;
const authService = inject ( AuthService );
// Mobile login
const loginPayload = {
email: '[email protected] ' ,
password: 'securePassword123' ,
appAudience: 'passenger_app' as const ,
expectedUserType: UserType . Passenger
};
authService . login ( loginPayload ). subscribe ({
next : ( response ) => {
console . log ( 'Access token:' , response . accessToken );
console . log ( 'Refresh token:' , response . refreshToken ); // mobile only
console . log ( 'Expires at:' , new Date ( response . accessTokenExpiresAt ));
},
error : ( err : ApiError ) => {
console . error ( 'Login failed:' , err . message );
if ( err . validation ) {
console . error ( 'Validation errors:' , err . validation );
}
}
});
// Web login with cookies
authService . login ( loginPayload , { withCredentials: true }). subscribe ( ... );
refresh()
Refreshes an expired access token. Supports both web (cookie) and mobile (token) flows.
refresh (
refreshToken ?: string ,
useCookie = false
): Observable < RefreshResponse >
Refresh token (required for mobile flows, unused for web)
Set to true for web flows to use HttpOnly cookies
New authentication tokens Show RefreshResponse properties
New refresh token (mobile only)
New access token expiration (epoch ms)
Usage Example
// Mobile refresh
const refreshToken = 'stored_refresh_token_here' ;
authService . refresh ( refreshToken , false ). subscribe ({
next : ( response ) => {
console . log ( 'New access token:' , response . accessToken );
console . log ( 'New refresh token:' , response . refreshToken );
// Store new tokens
},
error : ( err : ApiError ) => {
console . error ( 'Refresh failed:' , err . message );
// Redirect to login
}
});
// Web refresh (uses cookie)
authService . refresh ( undefined , true ). subscribe ({
next : ( response ) => {
console . log ( 'New access token:' , response . accessToken );
// Refresh token is in HttpOnly cookie
},
error : ( err ) => {
// Session expired, redirect to login
}
});
logoutWeb()
Logs out a web session (clears HttpOnly cookie).
logoutWeb (): Observable < void >
Usage Example
authService . logoutWeb (). subscribe ({
next : () => {
console . log ( 'Logged out successfully' );
// Redirect to login page
},
error : ( err : ApiError ) => {
console . error ( 'Logout failed:' , err . message );
}
});
logoutMobile()
Logs out a mobile session by invalidating the refresh token.
logoutMobile ( refreshToken : string ): Observable < void >
The refresh token to invalidate
Usage Example
const refreshToken = 'stored_refresh_token' ;
authService . logoutMobile ( refreshToken ). subscribe ({
next : () => {
console . log ( 'Logged out successfully' );
// Clear stored tokens
},
error : ( err : ApiError ) => {
console . error ( 'Logout failed:' , err . message );
}
});
me()
Fetches the current user’s profile.
me ( useCookie : boolean = true ): Observable < UserProfile >
Whether to send credentials via cookie (true for web, false for mobile)
User profile data Show UserProfile properties
URL to user’s profile picture
User type: 'passenger' | 'driver' | 'admin'
GeoJSON Point with user’s current location Coordinates as [longitude, latitude]
ISO 8601 timestamp of account creation
Usage Example
// Web (with cookies)
authService . me ( true ). subscribe ({
next : ( profile ) => {
console . log ( 'User:' , profile . name );
console . log ( 'Email:' , profile . email );
console . log ( 'Type:' , profile . userType );
if ( profile . currentLocation ) {
const [ lng , lat ] = profile . currentLocation . coordinates ;
console . log ( 'Location:' , lat , lng );
}
},
error : ( err : ApiError ) => {
console . error ( 'Failed to fetch profile:' , err . message );
}
});
// Mobile (with Authorization header)
authService . me ( false ). subscribe ( ... );
Error Handling
All methods use consistent error handling that normalizes errors into the ApiError interface:
export interface ApiError {
status ?: number ; // HTTP status code
message : string ; // Human-readable error message
code ?: string ; // Application error code
validation ?: Record < string , string []>; // Field validation errors
raw ?: any ; // Raw error response
url ?: string | null ; // Request URL
}
Error Handling Example
authService . login ( payload ). subscribe ({
next : ( response ) => { /* success */ },
error : ( err : ApiError ) => {
if ( err . status === 401 ) {
console . error ( 'Invalid credentials' );
} else if ( err . status === 422 && err . validation ) {
// Handle validation errors
Object . entries ( err . validation ). forEach (([ field , errors ]) => {
console . error ( ` ${ field } : ${ errors . join ( ', ' ) } ` );
});
} else if ( err . status === 0 ) {
console . error ( 'Network error:' , err . message );
} else {
console . error ( 'Error:' , err . message );
if ( err . code ) console . error ( 'Code:' , err . code );
}
}
});
TypeScript Interfaces
LoginPayload
export interface LoginPayload {
id ?: string ;
email ?: string ;
phoneNumber ?: string ;
password : string ;
location ?: Location ;
appAudience : AppAudience ;
expectedUserType : UserType ;
}
type AppAudience = 'driver_app' | 'passenger_app' | 'admin_panel' | 'api_client' ;
LoginResponse
export interface BaseAuthResponse {
accessToken : string ;
accessTokenExpiresAt : number ;
refreshTokenExpiresAt ?: number ;
sid ?: string ;
sessionType : SessionType ;
}
export interface LoginResponseMobile extends BaseAuthResponse {
refreshToken : string ;
}
export interface LoginResponseWeb extends BaseAuthResponse {
refreshToken ?: never ;
}
export type LoginResponse = LoginResponseMobile | LoginResponseWeb ;
RefreshResponse
export interface RefreshResponseMobile extends BaseAuthResponse {
refreshToken : string ;
}
export interface RefreshResponseWeb extends BaseAuthResponse {
refreshToken ?: never ;
}
export type RefreshResponse = RefreshResponseMobile | RefreshResponseWeb ;
UserProfile
export interface UserProfile {
id : string ;
name : string | null ;
email : string | null ;
phoneNumber ?: string | null ;
profilePictureUrl ?: string | null ;
userType : UserType ;
currentLocation ?: {
type : 'Point' ;
coordinates : [ number , number ];
} | null ;
createdAt ?: string ;
}
export enum UserType {
Passenger = 'passenger' ,
Driver = 'driver' ,
Admin = 'admin' ,
}
API Response Wrapper
The backend wraps responses in a standard format:
interface ApiResponse < T > {
success : boolean ;
message ?: string ;
data : T ;
}
The AuthService automatically unwraps the data field, so you receive the typed response directly.