210 lines
5.8 KiB
Dart
210 lines
5.8 KiB
Dart
import '../../../core/network/api_client.dart';
|
|
import '../../../core/network/api_endpoints.dart';
|
|
import '../../../core/error/exceptions.dart';
|
|
|
|
class AuthResult {
|
|
final String accessToken;
|
|
final String refreshToken;
|
|
final int expiresIn;
|
|
final UserInfo user;
|
|
|
|
AuthResult({
|
|
required this.accessToken,
|
|
required this.refreshToken,
|
|
required this.expiresIn,
|
|
required this.user,
|
|
});
|
|
|
|
factory AuthResult.fromJson(Map<String, dynamic> json) {
|
|
return AuthResult(
|
|
accessToken: json['accessToken'] as String,
|
|
refreshToken: json['refreshToken'] as String,
|
|
expiresIn: json['expiresIn'] as int,
|
|
user: UserInfo.fromJson(json['user'] as Map<String, dynamic>),
|
|
);
|
|
}
|
|
}
|
|
|
|
class UserInfo {
|
|
final String accountSequence;
|
|
final String phone;
|
|
final String source;
|
|
final String kycStatus;
|
|
final String? status;
|
|
final String? realName;
|
|
final DateTime? createdAt;
|
|
final DateTime? lastLoginAt;
|
|
|
|
UserInfo({
|
|
required this.accountSequence,
|
|
required this.phone,
|
|
required this.source,
|
|
required this.kycStatus,
|
|
this.status,
|
|
this.realName,
|
|
this.createdAt,
|
|
this.lastLoginAt,
|
|
});
|
|
|
|
factory UserInfo.fromJson(Map<String, dynamic> json) {
|
|
return UserInfo(
|
|
accountSequence: json['accountSequence'] as String,
|
|
phone: json['phone'] as String,
|
|
source: json['source'] as String,
|
|
kycStatus: json['kycStatus'] as String,
|
|
status: json['status'] as String?,
|
|
realName: json['realName'] as String?,
|
|
createdAt: json['createdAt'] != null
|
|
? DateTime.parse(json['createdAt'].toString())
|
|
: null,
|
|
lastLoginAt: json['lastLoginAt'] != null
|
|
? DateTime.parse(json['lastLoginAt'].toString())
|
|
: null,
|
|
);
|
|
}
|
|
|
|
bool get isKycVerified => kycStatus == 'VERIFIED';
|
|
}
|
|
|
|
abstract class AuthRemoteDataSource {
|
|
Future<void> sendSmsCode(String phone, String type);
|
|
Future<bool> verifySmsCode(String phone, String code, String type);
|
|
Future<AuthResult> register(String phone, String password, String smsCode);
|
|
Future<AuthResult> loginWithPassword(String phone, String password);
|
|
Future<AuthResult> loginWithSms(String phone, String smsCode);
|
|
Future<String> refreshToken(String refreshToken);
|
|
Future<void> logout(String refreshToken);
|
|
Future<UserInfo> getProfile();
|
|
Future<void> resetPassword(String phone, String smsCode, String newPassword);
|
|
Future<void> changePassword(String oldPassword, String newPassword);
|
|
}
|
|
|
|
class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
|
final ApiClient client;
|
|
|
|
AuthRemoteDataSourceImpl({required this.client});
|
|
|
|
@override
|
|
Future<void> sendSmsCode(String phone, String type) async {
|
|
try {
|
|
await client.post(
|
|
ApiEndpoints.sendSms,
|
|
data: {'phone': phone, 'type': type},
|
|
);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<bool> verifySmsCode(String phone, String code, String type) async {
|
|
try {
|
|
final response = await client.post(
|
|
ApiEndpoints.verifySms,
|
|
data: {'phone': phone, 'code': code, 'type': type},
|
|
);
|
|
return response.data['valid'] as bool? ?? false;
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<AuthResult> register(String phone, String password, String smsCode) async {
|
|
try {
|
|
final response = await client.post(
|
|
ApiEndpoints.register,
|
|
data: {'phone': phone, 'password': password, 'smsCode': smsCode},
|
|
);
|
|
return AuthResult.fromJson(response.data as Map<String, dynamic>);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<AuthResult> loginWithPassword(String phone, String password) async {
|
|
try {
|
|
final response = await client.post(
|
|
ApiEndpoints.login,
|
|
data: {'phone': phone, 'password': password},
|
|
);
|
|
return AuthResult.fromJson(response.data as Map<String, dynamic>);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<AuthResult> loginWithSms(String phone, String smsCode) async {
|
|
try {
|
|
final response = await client.post(
|
|
ApiEndpoints.loginSms,
|
|
data: {'phone': phone, 'smsCode': smsCode},
|
|
);
|
|
return AuthResult.fromJson(response.data as Map<String, dynamic>);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<String> refreshToken(String refreshToken) async {
|
|
try {
|
|
final response = await client.post(
|
|
ApiEndpoints.refreshToken,
|
|
data: {'refreshToken': refreshToken},
|
|
);
|
|
return response.data['accessToken'] as String;
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> logout(String refreshToken) async {
|
|
try {
|
|
await client.post(
|
|
ApiEndpoints.logout,
|
|
data: {'refreshToken': refreshToken},
|
|
);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<UserInfo> getProfile() async {
|
|
try {
|
|
final response = await client.get(ApiEndpoints.userProfile);
|
|
return UserInfo.fromJson(response.data as Map<String, dynamic>);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> resetPassword(String phone, String smsCode, String newPassword) async {
|
|
try {
|
|
await client.post(
|
|
ApiEndpoints.resetPassword,
|
|
data: {'phone': phone, 'smsCode': smsCode, 'newPassword': newPassword},
|
|
);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<void> changePassword(String oldPassword, String newPassword) async {
|
|
try {
|
|
await client.post(
|
|
ApiEndpoints.changePassword,
|
|
data: {'oldPassword': oldPassword, 'newPassword': newPassword},
|
|
);
|
|
} catch (e) {
|
|
throw ServerException(e.toString());
|
|
}
|
|
}
|
|
}
|