add auth
This commit is contained in:
@@ -20,6 +20,7 @@ class AuthLocalDataSource {
|
||||
static const String _fullNameKey = 'auth_session_full_name';
|
||||
static const String _createdAtKey = 'auth_session_created_at';
|
||||
static const String _appsKey = 'auth_session_apps';
|
||||
static const String _rememberMeKey = 'auth_remember_me';
|
||||
|
||||
AuthLocalDataSource(this._secureStorage);
|
||||
|
||||
@@ -102,21 +103,46 @@ class AuthLocalDataSource {
|
||||
return sid != null && csrfToken != null;
|
||||
}
|
||||
|
||||
/// Save "Remember Me" preference
|
||||
///
|
||||
/// If true, user session will be restored on next app launch.
|
||||
Future<void> saveRememberMe(bool rememberMe) async {
|
||||
await _secureStorage.write(
|
||||
key: _rememberMeKey,
|
||||
value: rememberMe.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Get "Remember Me" preference
|
||||
///
|
||||
/// Returns true if user wants to be remembered, false otherwise.
|
||||
Future<bool> getRememberMe() async {
|
||||
final value = await _secureStorage.read(key: _rememberMeKey);
|
||||
return value == 'true';
|
||||
}
|
||||
|
||||
/// Clear session data
|
||||
///
|
||||
/// Called during logout to remove all session information.
|
||||
/// Called during logout to remove all session information including rememberMe.
|
||||
Future<void> clearSession() async {
|
||||
// Clear all session data including rememberMe
|
||||
await _secureStorage.delete(key: _sidKey);
|
||||
await _secureStorage.delete(key: _csrfTokenKey);
|
||||
await _secureStorage.delete(key: _fullNameKey);
|
||||
await _secureStorage.delete(key: _createdAtKey);
|
||||
await _secureStorage.delete(key: _appsKey);
|
||||
await _secureStorage.delete(key: _rememberMeKey);
|
||||
}
|
||||
|
||||
/// Clear all authentication data
|
||||
/// Clear all authentication data including remember me
|
||||
///
|
||||
/// Complete cleanup of all stored auth data.
|
||||
Future<void> clearAll() async {
|
||||
await _secureStorage.deleteAll();
|
||||
await _secureStorage.delete(key: _sidKey);
|
||||
await _secureStorage.delete(key: _csrfTokenKey);
|
||||
await _secureStorage.delete(key: _fullNameKey);
|
||||
await _secureStorage.delete(key: _createdAtKey);
|
||||
await _secureStorage.delete(key: _appsKey);
|
||||
await _secureStorage.delete(key: _rememberMeKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,64 @@ class AuthRemoteDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/// Login
|
||||
///
|
||||
/// Authenticates user with phone number.
|
||||
/// Requires existing session (CSRF token and Cookie).
|
||||
/// Returns new session with user credentials.
|
||||
///
|
||||
/// API: POST /api/method/building_material.building_material.api.auth.login
|
||||
/// Body: { "username": "phone", "googleid": null, "facebookid": null, "zaloid": null }
|
||||
///
|
||||
/// Response includes new sid and csrf_token for authenticated user.
|
||||
Future<GetSessionResponse> login({
|
||||
required String phone,
|
||||
required String csrfToken,
|
||||
required String sid,
|
||||
String? password, // Reserved for future use
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/method/building_material.building_material.api.auth.login',
|
||||
data: {
|
||||
'username': phone,
|
||||
'googleid': null,
|
||||
'facebookid': null,
|
||||
'zaloid': null,
|
||||
// Password field reserved for future use
|
||||
// 'password': password,
|
||||
},
|
||||
options: Options(
|
||||
headers: {
|
||||
'X-Frappe-Csrf-Token': csrfToken,
|
||||
'Cookie': 'sid=$sid',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
return GetSessionResponse.fromJson(response.data!);
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Login failed: ${response.statusCode}',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 401) {
|
||||
throw const UnauthorizedException('Invalid credentials');
|
||||
} else if (e.response?.statusCode == 404) {
|
||||
throw NotFoundException('Login endpoint not found');
|
||||
} else {
|
||||
throw NetworkException(
|
||||
e.message ?? 'Failed to login',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw ServerException('Unexpected error during login: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Cities
|
||||
///
|
||||
/// Fetches list of cities/provinces for address selection.
|
||||
|
||||
Reference in New Issue
Block a user