198 lines
7.3 KiB
Dart
198 lines
7.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:html/parser.dart' as html_parser;
|
|
import 'package:inventory_system/services/api_service.dart';
|
|
import 'package:inventory_system/services/session_manager.dart';
|
|
|
|
class AuthService {
|
|
Future<Map<String, dynamic>> signIn({
|
|
required String usernameOrEmail,
|
|
required String password,
|
|
}) async {
|
|
if (usernameOrEmail.toLowerCase() == 'admin@pstw.com.my') {
|
|
return _performAdminWebLogin(usernameOrEmail, password);
|
|
} else {
|
|
return _performLdapApiLogin(usernameOrEmail, password);
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> _performLdapApiLogin(
|
|
String username, String password) async {
|
|
final Uri loginUri = Uri.parse('${ApiService.baseUrl}/IdentityAPI/LdapLogin');
|
|
final loginHeaders = {'Content-Type': 'application/json; charset=UTF-8'};
|
|
final loginBody = jsonEncode({'UserName': username, 'Password': password});
|
|
|
|
try {
|
|
final response = await http.post(loginUri, headers: loginHeaders, body: loginBody);
|
|
|
|
if (response.statusCode != 200) {
|
|
return _handleLdapError(response);
|
|
}
|
|
|
|
final String? sessionCookie = response.headers['set-cookie'];
|
|
if (sessionCookie == null) {
|
|
return {'success': false, 'message': 'Login succeeded, but failed to start a session.'};
|
|
}
|
|
SessionManager.instance.setCookie(sessionCookie);
|
|
|
|
return await _fetchLdapUserDetails(sessionCookie, username);
|
|
|
|
} on TimeoutException {
|
|
return {'success': false, 'message': 'The connection timed out. Please try again.'};
|
|
} on SocketException {
|
|
return {'success': false, 'message': 'Could not connect to the server. Please check your network.'};
|
|
} catch (e) {
|
|
debugPrint('An unexpected error occurred during LDAP login: $e');
|
|
return {'success': false, 'message': 'An unexpected error occurred.'};
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> fetchUserProfile() async {
|
|
final String? sessionCookie = SessionManager.instance.getCookie();
|
|
if (sessionCookie == null) {
|
|
return {'success': false, 'message': 'No active session found.'};
|
|
}
|
|
|
|
final Uri userInfoUri = Uri.parse('${ApiService.baseUrl}/IdentityAPI/GetUserInformation');
|
|
final headers = {'Cookie': sessionCookie};
|
|
|
|
try {
|
|
final response = await http.post(userInfoUri, headers: headers);
|
|
|
|
if (response.statusCode == 200) {
|
|
final userInfoResponse = jsonDecode(response.body);
|
|
final Map<String, dynamic>? userData = userInfoResponse['userInfo'];
|
|
|
|
if (userData == null) {
|
|
return {'success': false, 'message': 'User profile data is missing from the API response.'};
|
|
}
|
|
|
|
return {
|
|
'success': true,
|
|
'data': userData // Return raw user data as requested for display
|
|
};
|
|
} else {
|
|
return {'success': false, 'message': 'Failed to retrieve user profile. Status: ${response.statusCode}'};
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Error fetching user profile: $e');
|
|
return {'success': false, 'message': 'Error fetching user details.'};
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> _fetchLdapUserDetails(String sessionCookie, String username) async {
|
|
final Uri userInfoUri = Uri.parse('${ApiService.baseUrl}/IdentityAPI/GetUserInformation');
|
|
final headers = {'Cookie': sessionCookie};
|
|
|
|
try {
|
|
final response = await http.post(userInfoUri, headers: headers);
|
|
|
|
if (response.statusCode == 200) {
|
|
final userInfoResponse = jsonDecode(response.body);
|
|
final Map<String, dynamic>? userData = userInfoResponse['userInfo'];
|
|
|
|
if (userData == null) {
|
|
return {'success': false, 'message': 'User profile data is missing from the API response.'};
|
|
}
|
|
|
|
final List<dynamic> roles = userData['role'] ?? [];
|
|
final bool isInventoryMaster = roles.contains('Inventory Master');
|
|
final bool isSuperAdmin = roles.contains('Super Admin');
|
|
|
|
final Map<String, dynamic> sessionData = Map<String, dynamic>.from(userData);
|
|
sessionData['fullName'] = username;
|
|
sessionData['isAdmin'] = isInventoryMaster || isSuperAdmin;
|
|
sessionData['isInventoryMaster'] = isInventoryMaster;
|
|
sessionData['isSuperAdmin'] = isSuperAdmin;
|
|
sessionData['role'] = roles;
|
|
|
|
return {
|
|
'success': true,
|
|
'data': sessionData
|
|
};
|
|
} else {
|
|
return {'success': false, 'message': 'Logged in, but failed to retrieve user profile.'};
|
|
}
|
|
} catch (e) {
|
|
return {'success': false, 'message': 'Error fetching user details after login.'};
|
|
}
|
|
}
|
|
|
|
Map<String, dynamic> _handleLdapError(http.Response response) {
|
|
try {
|
|
final errorData = jsonDecode(response.body);
|
|
String errorMessage = errorData['message'] ?? 'An unknown error occurred';
|
|
|
|
if (errorMessage.toLowerCase().contains('was not found')) {
|
|
return {'success': false, 'message': 'Wrong username or email.'};
|
|
} else if (errorMessage.toLowerCase().contains('incorrect password.')) {
|
|
return {'success': false, 'message': 'Wrong password.'};
|
|
} else {
|
|
return {'success': false, 'message': errorMessage};
|
|
}
|
|
} catch (e) {
|
|
return {'success': false, 'message': 'Login failed with status: ${response.statusCode}'};
|
|
}
|
|
}
|
|
|
|
Future<Map<String, dynamic>> _performAdminWebLogin(
|
|
String email, String password) async {
|
|
final Uri loginUri = Uri.parse('${ApiService.baseUrl}/Identity/Account/Login');
|
|
|
|
try {
|
|
final getResponse = await http.get(loginUri);
|
|
final String? sessionCookie = getResponse.headers['set-cookie'];
|
|
final document = html_parser.parse(getResponse.body);
|
|
final token = document.querySelector('input[name="__RequestVerificationToken"]')?.attributes['value'];
|
|
|
|
if (sessionCookie == null || token == null) {
|
|
return {'success': false, 'message': 'Failed to prepare a secure login session.'};
|
|
}
|
|
|
|
SessionManager.instance.setCookie(sessionCookie);
|
|
|
|
final postResponse = await http.post(
|
|
loginUri,
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Cookie': sessionCookie,
|
|
},
|
|
body: {
|
|
'Email': email,
|
|
'Password': password,
|
|
'RememberMe': 'false',
|
|
'__RequestVerificationToken': token,
|
|
},
|
|
);
|
|
|
|
if (postResponse.statusCode == 302) {
|
|
// After a successful login, the server issues a new, authenticated cookie.
|
|
// We must capture and save this new cookie from the POST response.
|
|
final String? newSessionCookie = postResponse.headers['set-cookie'];
|
|
if (newSessionCookie != null) {
|
|
SessionManager.instance.setCookie(newSessionCookie);
|
|
}
|
|
|
|
return {
|
|
'success': true,
|
|
'data': {
|
|
'fullName': 'Super Admin',
|
|
'isAdmin': true,
|
|
'isInventoryMaster': false,
|
|
'isSuperAdmin': true,
|
|
'role': ['Super Admin'],
|
|
}
|
|
};
|
|
} else {
|
|
return {'success': false, 'message': 'Admin login failed. Please check credentials.'};
|
|
}
|
|
} catch (e) {
|
|
debugPrint('An unexpected error occurred during Admin login: $e');
|
|
return {'success': false, 'message': 'An unexpected error occurred.'};
|
|
}
|
|
}
|
|
}
|