105 lines
3.0 KiB
Dart
105 lines
3.0 KiB
Dart
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');
|
|
}
|
|
}
|