Stabilize auth flow and profile images
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../../core/network/api_error.dart';
|
||||
import '../domain/auth_models.dart';
|
||||
|
||||
class AuthApiClient {
|
||||
const AuthApiClient({
|
||||
required this.httpClient,
|
||||
required this.baseUri,
|
||||
this.timeout = const Duration(seconds: 10),
|
||||
});
|
||||
|
||||
final http.Client httpClient;
|
||||
final Uri baseUri;
|
||||
final Duration timeout;
|
||||
|
||||
Future<PhoneLoginResponse> phoneLogin(PhoneLoginRequest request) async {
|
||||
final response = await httpClient
|
||||
.post(
|
||||
_resolve('/api/v1/tdc114plus/auth/phone-login'),
|
||||
headers: const {
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: jsonEncode(request.toJson()),
|
||||
)
|
||||
.timeout(timeout);
|
||||
|
||||
final decoded = _decodeObject(response.body);
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
throw ApiException(
|
||||
statusCode: response.statusCode,
|
||||
apiError: ApiError.fromJson(decoded),
|
||||
);
|
||||
}
|
||||
return PhoneLoginResponse.fromJson(decoded);
|
||||
}
|
||||
|
||||
Future<PhoneLoginLinkInitResponse> requestPhoneLoginLink(
|
||||
PhoneLoginLinkInitRequest request,
|
||||
) async {
|
||||
final response = await httpClient
|
||||
.post(
|
||||
_resolve('/api/v1/auth/link/init'),
|
||||
headers: const {
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: jsonEncode(request.toJson()),
|
||||
)
|
||||
.timeout(timeout);
|
||||
|
||||
final decoded = _decodeObject(response.body);
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
throw ApiException(
|
||||
statusCode: response.statusCode,
|
||||
apiError: ApiError.fromJson(decoded),
|
||||
);
|
||||
}
|
||||
return PhoneLoginLinkInitResponse.fromJson(decoded);
|
||||
}
|
||||
|
||||
Future<PhoneLoginLinkPollResponse> pollPhoneLoginLink(
|
||||
PhoneLoginLinkPollRequest request,
|
||||
) async {
|
||||
final response = await httpClient
|
||||
.post(
|
||||
_resolve('/api/v1/auth/link/poll'),
|
||||
headers: const {
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: jsonEncode(request.toJson()),
|
||||
)
|
||||
.timeout(timeout);
|
||||
|
||||
final decoded = _decodeObject(response.body);
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
throw ApiException(
|
||||
statusCode: response.statusCode,
|
||||
apiError: ApiError.fromJson(decoded),
|
||||
);
|
||||
}
|
||||
return PhoneLoginLinkPollResponse.fromJson(decoded);
|
||||
}
|
||||
|
||||
Uri _resolve(String path) {
|
||||
final normalizedBase = baseUri.path.endsWith('/')
|
||||
? baseUri
|
||||
: baseUri.replace(path: '${baseUri.path}/');
|
||||
return normalizedBase.resolve(path.replaceFirst(RegExp(r'^/'), ''));
|
||||
}
|
||||
|
||||
Map<String, dynamic> _decodeObject(String body) {
|
||||
final decoded = jsonDecode(body);
|
||||
if (decoded is Map<String, dynamic>) {
|
||||
return decoded;
|
||||
}
|
||||
throw const FormatException('Expected JSON object response');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user