Files
Sven laptop 9d1a37e248
Build and Push Docker Images / detect-changes (push) Successful in 10s
Build and Push Docker Images / build-auth-api (push) Successful in 58s
Build and Push Docker Images / build-employee-api (push) Successful in 58s
Build and Push Docker Images / build-transit-api (push) Successful in 59s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m8s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m14s
Build and Push Docker Images / deploy-test-node (push) Successful in 5s
Update readme's, branches and actions
2026-09-17 12:04:44 +02:00

96 lines
2.6 KiB
Dart

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../models/user.dart';
import 'error_log_service.dart';
/// Authentication Service
class AuthService {
static const String _apiBaseUrl = 'https://transit.xtransit.testinstance.nl';
static const String _tokenKey = 'auth_token';
late SharedPreferences _prefs;
Future<void> _reportError(String partOfService, Object error) {
return ErrorLogService.report(
service: 'bus_terminal',
partOfService: partOfService,
error: error.toString(),
);
}
Future<void> _initPrefs() async {
_prefs = await SharedPreferences.getInstance();
}
/// Login with userCode and password
Future<AuthResponse> login({
required int userCode,
required String password,
}) async {
await _initPrefs();
try {
final response = await http.post(
Uri.parse('$_apiBaseUrl/login'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'userCode': userCode,
'password': password,
}),
);
if (response.statusCode == 200) {
final body = response.body;
try {
final data = jsonDecode(body) as Map<String, dynamic>;
final authResponse = AuthResponse.fromJson(data);
// Store token
await _prefs.setString(_tokenKey, authResponse.token);
return authResponse;
} catch (e) {
await _reportError('AuthService.login.parse', e);
// Surface the response body to help debug backend field names / formats
throw Exception('Login parse error: $e -- response body: $body');
}
} else if (response.statusCode == 401) {
throw Exception('Invalid credentials');
} else {
throw Exception('Login failed: ${response.statusCode}');
}
} catch (e) {
await _reportError('AuthService.login', e);
throw Exception('Login error: $e');
}
}
/// Get stored token
Future<String?> getToken() async {
await _initPrefs();
return _prefs.getString(_tokenKey);
}
/// Check if user is logged in
Future<bool> isLoggedIn() async {
final token = await getToken();
return token != null;
}
/// Logout
Future<void> logout() async {
await _initPrefs();
await _prefs.remove(_tokenKey);
}
/// Get Authorization header
Future<Map<String, String>> getAuthHeaders() async {
final token = await getToken();
return {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
};
}
}