forked from baron/baron-sso
userfront&backend test coverage 추가
This commit is contained in:
@@ -6,7 +6,18 @@ import 'auth_token_store.dart';
|
||||
import 'log_policy.dart';
|
||||
import 'runtime_env.dart';
|
||||
|
||||
typedef AuthProxyHttpClientFactory =
|
||||
http.Client Function({bool withCredentials});
|
||||
|
||||
class AuthProxyService {
|
||||
static AuthProxyHttpClientFactory? _httpClientFactoryForTesting;
|
||||
|
||||
static void debugSetHttpClientFactoryForTesting(
|
||||
AuthProxyHttpClientFactory? factory,
|
||||
) {
|
||||
_httpClientFactoryForTesting = factory;
|
||||
}
|
||||
|
||||
static String get _baseUrl => runtimeBackendUrl();
|
||||
|
||||
static bool get _isProd {
|
||||
@@ -32,9 +43,71 @@ class AuthProxyService {
|
||||
);
|
||||
}
|
||||
|
||||
static http.Client _createClient({bool withCredentials = false}) {
|
||||
final factory = _httpClientFactoryForTesting;
|
||||
if (factory != null) {
|
||||
return factory(withCredentials: withCredentials);
|
||||
}
|
||||
return createHttpClient(withCredentials: withCredentials);
|
||||
}
|
||||
|
||||
static Future<http.Response> _get(
|
||||
Uri url, {
|
||||
Map<String, String>? headers,
|
||||
bool withCredentials = false,
|
||||
}) async {
|
||||
final client = _createClient(withCredentials: withCredentials);
|
||||
try {
|
||||
return await client.get(url, headers: headers);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<http.Response> _post(
|
||||
Uri url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
bool withCredentials = false,
|
||||
}) async {
|
||||
final client = _createClient(withCredentials: withCredentials);
|
||||
try {
|
||||
return await client.post(url, headers: headers, body: body);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<http.Response> _patch(
|
||||
Uri url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
bool withCredentials = false,
|
||||
}) async {
|
||||
final client = _createClient(withCredentials: withCredentials);
|
||||
try {
|
||||
return await client.patch(url, headers: headers, body: body);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<http.Response> _delete(
|
||||
Uri url, {
|
||||
Map<String, String>? headers,
|
||||
bool withCredentials = false,
|
||||
}) async {
|
||||
final client = _createClient(withCredentials: withCredentials);
|
||||
try {
|
||||
return await client.delete(url, headers: headers);
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> fetchPasswordPolicy() async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/password/policy');
|
||||
final response = await http.get(url);
|
||||
final response = await _get(url);
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
@@ -47,24 +120,20 @@ class AuthProxyService {
|
||||
|
||||
static Future<Map<String, dynamic>> checkCookieSession() async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/user/me');
|
||||
final client = createHttpClient(withCredentials: true);
|
||||
try {
|
||||
final response = await client.get(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
);
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
withCredentials: true,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
}
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.profile_load',
|
||||
'Failed to load the profile: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
}
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.profile_load',
|
||||
'Failed to load the profile: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> getMe({
|
||||
@@ -72,25 +141,24 @@ class AuthProxyService {
|
||||
bool useCookie = true,
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/user/me');
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
try {
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await client.get(url, headers: headers);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
}
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.profile_load',
|
||||
'Failed to load the profile: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
} finally {
|
||||
client.close();
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
}
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.profile_load',
|
||||
'Failed to load the profile: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<int> getSessionStatus({
|
||||
@@ -98,22 +166,21 @@ class AuthProxyService {
|
||||
bool useCookie = false,
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/user/me');
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
try {
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await client.get(url, headers: headers);
|
||||
return response.statusCode;
|
||||
} finally {
|
||||
client.close();
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
return response.statusCode;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> getTenantInfo() async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/tenant-info');
|
||||
final response = await http.get(url);
|
||||
final response = await _get(url);
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
@@ -144,7 +211,7 @@ class AuthProxyService {
|
||||
body['codeOnly'] = true;
|
||||
}
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(body),
|
||||
@@ -166,7 +233,7 @@ class AuthProxyService {
|
||||
) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/enchanted-link/poll');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'pendingRef': pendingRef}),
|
||||
@@ -191,7 +258,7 @@ class AuthProxyService {
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/magic-link/verify');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'token': token, 'verifyOnly': verifyOnly}),
|
||||
@@ -225,7 +292,7 @@ class AuthProxyService {
|
||||
payload['pendingRef'] = pendingRef;
|
||||
}
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
@@ -246,22 +313,21 @@ class AuthProxyService {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/user/sessions/$sessionId');
|
||||
final useCookie = AuthTokenStore.usesCookie();
|
||||
final token = AuthTokenStore.getToken();
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
try {
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await client.delete(url, headers: headers);
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.dashboard.sessions.revoke',
|
||||
'Failed to revoke the session: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await _delete(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.dashboard.sessions.revoke',
|
||||
'Failed to revoke the session: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,35 +335,34 @@ class AuthProxyService {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/user/sessions');
|
||||
final useCookie = AuthTokenStore.usesCookie();
|
||||
final token = AuthTokenStore.getToken();
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
try {
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await client.get(url, headers: headers);
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.dashboard.sessions.load',
|
||||
'Failed to load the active sessions: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.dashboard.sessions.load',
|
||||
'Failed to load the active sessions: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
|
||||
final body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final items = (body['items'] as List?) ?? const [];
|
||||
for (final item in items.whereType<Map<String, dynamic>>()) {
|
||||
if (item['is_current'] == true) {
|
||||
final sessionId = item['session_id']?.toString().trim() ?? '';
|
||||
if (sessionId.isNotEmpty) {
|
||||
return sessionId;
|
||||
}
|
||||
final body = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
final items = (body['items'] as List?) ?? const [];
|
||||
for (final item in items.whereType<Map<String, dynamic>>()) {
|
||||
if (item['is_current'] == true) {
|
||||
final sessionId = item['session_id']?.toString().trim() ?? '';
|
||||
if (sessionId.isNotEmpty) {
|
||||
return sessionId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
client.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> verifyLoginShortCode(
|
||||
@@ -306,7 +371,7 @@ class AuthProxyService {
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/login/code/verify-short');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'shortCode': shortCode, 'verifyOnly': verifyOnly}),
|
||||
@@ -337,7 +402,7 @@ class AuthProxyService {
|
||||
'login_challenge': loginChallenge,
|
||||
};
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
@@ -360,29 +425,24 @@ class AuthProxyService {
|
||||
final url = Uri.parse(
|
||||
'$_baseUrl/api/v1/auth/consent',
|
||||
).replace(queryParameters: {'consent_challenge': consentChallenge});
|
||||
final client = createHttpClient(withCredentials: true);
|
||||
try {
|
||||
final response = await client.get(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
);
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
withCredentials: true,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
final rawDetails = errorBody['details'];
|
||||
throw AuthProxyException(
|
||||
errorCode: (errorBody['code'] ?? '').toString(),
|
||||
message:
|
||||
(errorBody['error'] ??
|
||||
tr('err.userfront.auth_proxy.consent_fetch'))
|
||||
.toString(),
|
||||
details: rawDetails is Map<String, dynamic> ? rawDetails : null,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
final rawDetails = errorBody['details'];
|
||||
throw AuthProxyException(
|
||||
errorCode: (errorBody['code'] ?? '').toString(),
|
||||
message:
|
||||
(errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_fetch'))
|
||||
.toString(),
|
||||
details: rawDetails is Map<String, dynamic> ? rawDetails : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,24 +456,20 @@ class AuthProxyService {
|
||||
body['grant_scope'] = grantScope;
|
||||
}
|
||||
|
||||
final client = createHttpClient(withCredentials: true);
|
||||
try {
|
||||
final response = await client.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(body),
|
||||
withCredentials: true,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_accept'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_accept'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,24 +479,20 @@ class AuthProxyService {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/consent/reject');
|
||||
final body = <String, dynamic>{'consent_challenge': consentChallenge};
|
||||
|
||||
final client = createHttpClient(withCredentials: true);
|
||||
try {
|
||||
final response = await client.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(body),
|
||||
);
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(body),
|
||||
withCredentials: true,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_reject'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.consent_reject'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,24 +505,20 @@ class AuthProxyService {
|
||||
if (token != null && token.isNotEmpty) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
final client = createHttpClient(withCredentials: true);
|
||||
try {
|
||||
final response = await client.post(
|
||||
url,
|
||||
headers: headers,
|
||||
body: jsonEncode({'login_challenge': loginChallenge}),
|
||||
);
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: headers,
|
||||
body: jsonEncode({'login_challenge': loginChallenge}),
|
||||
withCredentials: true,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.oidc_accept'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
return jsonDecode(response.body);
|
||||
} else {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.oidc_accept'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +527,7 @@ class AuthProxyService {
|
||||
bool? drySend,
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/password/reset/initiate');
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
@@ -514,7 +562,7 @@ class AuthProxyService {
|
||||
final url = Uri.parse(
|
||||
'$_baseUrl/api/v1/auth/password/reset/complete',
|
||||
).replace(queryParameters: query);
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'newPassword': newPassword}),
|
||||
@@ -534,7 +582,7 @@ class AuthProxyService {
|
||||
static Future<void> sendSms(String phoneNumber) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/sms');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'phoneNumber': phoneNumber}),
|
||||
@@ -555,7 +603,7 @@ class AuthProxyService {
|
||||
) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/verify-sms');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'phoneNumber': phoneNumber, 'code': code}),
|
||||
@@ -574,7 +622,7 @@ class AuthProxyService {
|
||||
|
||||
static Future<Map<String, dynamic>> initQrLogin() async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/qr/init');
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
);
|
||||
@@ -592,7 +640,7 @@ class AuthProxyService {
|
||||
|
||||
static Future<Map<String, dynamic>> pollQrStatus(String pendingRef) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/qr/poll');
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'pendingRef': pendingRef}),
|
||||
@@ -624,39 +672,26 @@ class AuthProxyService {
|
||||
payload['token'] = token;
|
||||
}
|
||||
|
||||
http.Client? client;
|
||||
try {
|
||||
if (withCredentials) {
|
||||
client = createHttpClient(withCredentials: true);
|
||||
}
|
||||
final response = await (client != null
|
||||
? client.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
)
|
||||
: http.post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
));
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
withCredentials: withCredentials,
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.qr_approve',
|
||||
'Failed to approve QR login: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client?.close();
|
||||
if (response.statusCode != 200) {
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.qr_approve',
|
||||
'Failed to approve QR login: {{error}}',
|
||||
detail: response.body,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> checkAdminAuth(String adminPassword) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/admin/check');
|
||||
try {
|
||||
final response = await http.get(
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -678,7 +713,7 @@ class AuthProxyService {
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/admin/users');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -710,7 +745,7 @@ class AuthProxyService {
|
||||
uri = uri.replace(queryParameters: {'text': query});
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
final response = await _get(
|
||||
uri,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -734,7 +769,7 @@ class AuthProxyService {
|
||||
final encodedId = Uri.encodeComponent(loginId);
|
||||
final url = Uri.parse('$_baseUrl/api/v1/admin/users/$encodedId');
|
||||
|
||||
final response = await http.delete(
|
||||
final response = await _delete(
|
||||
url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -759,7 +794,7 @@ class AuthProxyService {
|
||||
final encodedId = Uri.encodeComponent(loginId);
|
||||
final url = Uri.parse('$_baseUrl/api/v1/admin/users/$encodedId/status');
|
||||
|
||||
final response = await http.patch(
|
||||
final response = await _patch(
|
||||
url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -792,7 +827,7 @@ class AuthProxyService {
|
||||
if (phone != null) body['phone'] = phone;
|
||||
if (displayName != null) body['displayName'] = displayName;
|
||||
|
||||
final response = await http.patch(
|
||||
final response = await _patch(
|
||||
url,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -815,26 +850,25 @@ class AuthProxyService {
|
||||
final useCookie = AuthTokenStore.usesCookie();
|
||||
final token = AuthTokenStore.getToken();
|
||||
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
|
||||
try {
|
||||
final response = await client.get(url, headers: headers);
|
||||
final response = await _get(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
return data['items'] ?? [];
|
||||
} else {
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.linked_apps_load',
|
||||
'Failed to load linked applications.',
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
return data['items'] ?? [];
|
||||
} else {
|
||||
throw _error(
|
||||
'err.userfront.auth_proxy.linked_apps_load',
|
||||
'Failed to load linked applications.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,24 +877,22 @@ class AuthProxyService {
|
||||
final useCookie = AuthTokenStore.usesCookie();
|
||||
final token = AuthTokenStore.getToken();
|
||||
|
||||
final client = createHttpClient(withCredentials: useCookie);
|
||||
final headers = <String, String>{'Content-Type': 'application/json'};
|
||||
if (!useCookie && token != null) {
|
||||
headers['Authorization'] = 'Bearer $token';
|
||||
}
|
||||
|
||||
try {
|
||||
final response = await client.delete(url, headers: headers);
|
||||
final response = await _delete(
|
||||
url,
|
||||
headers: headers,
|
||||
withCredentials: useCookie,
|
||||
);
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ??
|
||||
tr('err.userfront.auth_proxy.linked_app_revoke'),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
client.close();
|
||||
if (response.statusCode != 200) {
|
||||
final errorBody = jsonDecode(response.body);
|
||||
throw Exception(
|
||||
errorBody['error'] ?? tr('err.userfront.auth_proxy.linked_app_revoke'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,7 +920,7 @@ class AuthProxyService {
|
||||
final sanitizedMessage = LogPolicy.sanitizeMessage(message);
|
||||
final sanitizedData = data == null ? null : LogPolicy.sanitizeData(data);
|
||||
try {
|
||||
await http.post(
|
||||
await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
@@ -945,7 +977,7 @@ class AuthProxyService {
|
||||
|
||||
static Future<bool> checkEmailAvailability(String email) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/signup/check-email');
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'email': email}),
|
||||
@@ -967,7 +999,7 @@ class AuthProxyService {
|
||||
if (tenantSlug != null && tenantSlug.isNotEmpty) {
|
||||
bodyData['tenantSlug'] = tenantSlug;
|
||||
}
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode(bodyData),
|
||||
@@ -997,7 +1029,7 @@ class AuthProxyService {
|
||||
}
|
||||
|
||||
final url = Uri.parse(uriString);
|
||||
final response = await http.get(url);
|
||||
final response = await _get(url);
|
||||
if (response.statusCode == 200) {
|
||||
final List<dynamic> list = jsonDecode(response.body);
|
||||
return list.cast<Map<String, dynamic>>();
|
||||
@@ -1009,7 +1041,7 @@ class AuthProxyService {
|
||||
final path = type == 'email' ? 'send-email-code' : 'send-sms-code';
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/signup/$path');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'target': target}),
|
||||
@@ -1031,7 +1063,7 @@ class AuthProxyService {
|
||||
) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/signup/verify-code');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({'target': target, 'type': type, 'code': code}),
|
||||
@@ -1055,7 +1087,7 @@ class AuthProxyService {
|
||||
}) async {
|
||||
final url = Uri.parse('$_baseUrl/api/v1/auth/signup');
|
||||
|
||||
final response = await http.post(
|
||||
final response = await _post(
|
||||
url,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: jsonEncode({
|
||||
|
||||
Reference in New Issue
Block a user