Skip to main content

User Authentication

Viax provides secure authentication with email/password login, device tracking, and password recovery options.

Login Process

Standard Login

1

Enter Email

Provide the email address used during registration
2

Enter Password

Type your account password
3

Device Verification

System validates device and credentials
4

Access Granted

Redirected to appropriate home screen

Login Screen Implementation

// lib/src/features/auth/presentation/screens/login_screen.dart

Future<void> _login() async {
  if (_formKey.currentState!.validate()) {
    setState(() => _isLoading = true);
    
    try {
      String emailToUse = _emailController.text.trim();
      
      // Get device UUID for security
      final deviceUuid = await DeviceIdService.getOrCreateDeviceUuid();
      
      // Attempt login
      final resp = await UserService.login(
        email: emailToUse,
        password: _passwordController.text,
        deviceUuid: deviceUuid,
      );
      
      if (resp['success'] == true) {
        // Save session
        final user = resp['data']?['user'];
        await UserService.saveSession(user);
        
        // Navigate based on user type
        final tipoUsuario = user?['tipo_usuario'] ?? 'cliente';
        _navigateToHome(tipoUsuario, user);
      }
    } catch (e) {
      _showError(e.toString());
    }
  }
}
// Service call
final response = await UserService.login(
  email: '[email protected]',
  password: 'userPassword123',
  deviceUuid: 'device-uuid-string',
);

User Type Routing

Automatic Navigation

Viax supports multiple user types with automatic routing:

Regular User

// Navigate to user home
Navigator.pushNamedAndRemoveUntil(
  context,
  RouteNames.home,
  (route) => false,
  arguments: {'email': email, 'user': user},
);
Home Screen: /home (user home screen)

Password Recovery

Forgot Password Flow

1

Request Reset

Click “Forgot Password?” on login screen
2

Enter Email

Provide registered email address
3

Verify Code

Enter 6-digit code sent to email
4

Set New Password

Create and confirm new password

Implementation

// lib/src/features/auth/presentation/screens/forgot_password_screen.dart

Future<void> _requestPasswordReset() async {
  final email = _emailController.text.trim();
  
  try {
    final response = await UserService.requestPasswordReset(
      email: email,
    );
    
    if (response['success']) {
      // Navigate to verification screen
      Navigator.pushNamed(
        context,
        RouteNames.passwordRecoveryVerification,
        arguments: {'email': email},
      );
    }
  } catch (e) {
    showError(e.toString());
  }
}

Verification & Reset

// password_recovery_verification_screen.dart

final response = await UserService.verifyResetCode(
  email: email,
  code: verificationCode,
);

if (response['success']) {
  // Navigate to set new password screen
  Navigator.pushNamed(
    context,
    RouteNames.setNewPasswordAfterVerification,
    arguments: {'email': email, 'code': verificationCode},
  );
}

Device Security

Device UUID Tracking

Viax tracks devices for security:
// lib/src/global/services/device_id_service.dart

class DeviceIdService {
  static Future<String> getOrCreateDeviceUuid() async {
    final prefs = await SharedPreferences.getInstance();
    String? uuid = prefs.getString(_kDeviceUuidKey);
    
    if (uuid == null || uuid.isEmpty) {
      // Generate new UUID
      uuid = const Uuid().v4();
      await prefs.setString(_kDeviceUuidKey, uuid);
    }
    
    return uuid;
  }
}
Why Device Tracking?
  • Prevent unauthorized access
  • Detect suspicious login attempts
  • Enable multi-device management
  • Support device-specific features

Failed Login Protection

Rate Limiting

// Track failed attempts
int _localFailAttempts = 0;

if (message.contains('Contraseña')) {
  _localFailAttempts = failAttempts;
  
  if (tooMany || _localFailAttempts >= 5) {
    // Require email verification for security
    Navigator.pushReplacementNamed(
      context,
      RouteNames.emailVerification,
      arguments: {
        'email': emailToUse,
        'userName': emailToUse.split('@')[0],
        'deviceUuid': deviceUuid,
      },
    );
  }
}
Account Protection: After 5 failed login attempts, you’ll need to verify your email before logging in again.

Session Management

Saving User Session

// lib/src/global/services/auth/user_service.dart

static Future<void> saveSession(Map<String, dynamic> userData) async {
  final prefs = await SharedPreferences.getInstance();
  
  // Store user data
  await prefs.setInt('user_id', userData['id']);
  await prefs.setString('user_email', userData['email']);
  await prefs.setString('user_name', userData['nombre']);
  await prefs.setString('user_type', userData['tipo_usuario']);
  
  // Store full user object as JSON
  await prefs.setString('user_session', jsonEncode(userData));
}

Retrieving Session

static Future<Map<String, dynamic>?> getSavedSession() async {
  final prefs = await SharedPreferences.getInstance();
  final sessionString = prefs.getString('user_session');
  
  if (sessionString != null) {
    return jsonDecode(sessionString) as Map<String, dynamic>;
  }
  
  return null;
}

Clearing Session (Logout)

static Future<void> clearSession() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.clear(); // Clear all stored data
}

Auto-Login

Persistent Sessions

// Check for existing session on app start
@override
void initState() {
  super.initState();
  _checkExistingSession();
}

Future<void> _checkExistingSession() async {
  final session = await UserService.getSavedSession();
  
  if (session != null && session['email'] != null) {
    // User has active session - auto-navigate
    final userType = session['tipo_usuario'] ?? 'cliente';
    _navigateToHome(userType, session);
  } else {
    // No session - show login
    setState(() => _isLoading = false);
  }
}

Security Best Practices

  • Minimum Length: 6 characters required
  • Hashing: Passwords hashed with bcrypt on backend
  • Never Stored Plain: Only hashed values in database
  • HTTPS Only: All auth requests over secure connection
  • Unique Device ID: Generated per installation
  • Device Tracking: Monitor login locations
  • Suspicious Activity: Alert on unusual patterns
  • Multi-Device Support: Login from multiple devices
  • Local Storage: Encrypted SharedPreferences
  • Auto-Logout: After extended inactivity
  • Secure Tokens: JWT with expiration
  • Refresh Tokens: Background session renewal

Common Issues

Troubleshooting

Problem: “Email or password incorrect”Solutions:
  1. Verify email is spelled correctly
  2. Check password (case-sensitive)
  3. Use “Forgot Password” if needed
  4. Ensure account was created successfully

Next Steps

Profile Management

Update your account details

Book Your First Ride

Start using Viax

Build docs developers (and LLMs) love