chore: remove unused profile lock migration and admin_profile_service
This commit is contained in:
@@ -22,11 +22,7 @@ class AdminUserQuery {
|
||||
/// Full text search query.
|
||||
final String searchQuery;
|
||||
|
||||
AdminUserQuery copyWith({
|
||||
int? offset,
|
||||
int? limit,
|
||||
String? searchQuery,
|
||||
}) {
|
||||
AdminUserQuery copyWith({int? offset, int? limit, String? searchQuery}) {
|
||||
return AdminUserQuery(
|
||||
offset: offset ?? this.offset,
|
||||
limit: limit ?? this.limit,
|
||||
@@ -35,7 +31,9 @@ class AdminUserQuery {
|
||||
}
|
||||
}
|
||||
|
||||
final adminUserQueryProvider = StateProvider<AdminUserQuery>((ref) => const AdminUserQuery());
|
||||
final adminUserQueryProvider = StateProvider<AdminUserQuery>(
|
||||
(ref) => const AdminUserQuery(),
|
||||
);
|
||||
|
||||
final adminUserControllerProvider = Provider<AdminUserController>((ref) {
|
||||
final client = ref.watch(supabaseClientProvider);
|
||||
@@ -77,66 +75,111 @@ class AdminUserController {
|
||||
await _client.from('profiles').update({'role': role}).eq('id', userId);
|
||||
}
|
||||
|
||||
/// Password administration — forwarded to the admin Edge Function.
|
||||
Future<void> setPassword({
|
||||
required String userId,
|
||||
required String password,
|
||||
}) async {
|
||||
await _invokeAdminFunction(
|
||||
action: 'set_password',
|
||||
payload: {'userId': userId, 'password': password},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setLock({required String userId, required bool locked}) async {
|
||||
await _invokeAdminFunction(
|
||||
action: 'set_lock',
|
||||
payload: {'userId': userId, 'locked': locked},
|
||||
);
|
||||
}
|
||||
|
||||
Future<AdminUserStatus> fetchStatus(String userId) async {
|
||||
final data = await _invokeAdminFunction(
|
||||
action: 'get_user',
|
||||
payload: {'userId': userId},
|
||||
);
|
||||
final user = (data as Map<String, dynamic>)['user'] as Map<String, dynamic>;
|
||||
final bannedUntilRaw = user['banned_until'] as String?;
|
||||
final bannedUntilParsed = bannedUntilRaw == null
|
||||
? null
|
||||
: DateTime.tryParse(bannedUntilRaw);
|
||||
return AdminUserStatus(
|
||||
email: user['email'] as String?,
|
||||
bannedUntil: bannedUntilParsed == null
|
||||
? null
|
||||
: AppTime.toAppTime(bannedUntilParsed),
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> _invokeAdminFunction({
|
||||
required String action,
|
||||
required Map<String, dynamic> payload,
|
||||
}) async {
|
||||
final payload = {
|
||||
'action': 'set_password',
|
||||
'userId': userId,
|
||||
'password': password,
|
||||
};
|
||||
final accessToken = _client.auth.currentSession?.accessToken;
|
||||
final response = await _client.functions.invoke(
|
||||
'admin_user_management',
|
||||
body: {'action': action, ...payload},
|
||||
body: payload,
|
||||
headers: accessToken == null
|
||||
? null
|
||||
: {'Authorization': 'Bearer $accessToken'},
|
||||
);
|
||||
if (response.status != 200) {
|
||||
throw Exception(_extractErrorMessage(response.data));
|
||||
throw Exception(response.data ?? 'Failed to reset password');
|
||||
}
|
||||
return response.data;
|
||||
}
|
||||
|
||||
String _extractErrorMessage(dynamic data) {
|
||||
if (data is Map<String, dynamic>) {
|
||||
final error = data['error'];
|
||||
if (error is String && error.trim().isNotEmpty) {
|
||||
return error;
|
||||
}
|
||||
final message = data['message'];
|
||||
if (message is String && message.trim().isNotEmpty) {
|
||||
return message;
|
||||
}
|
||||
/// Set/unset a user's ban/lock via the admin Edge Function (preferred).
|
||||
Future<void> setLock({required String userId, required bool locked}) async {
|
||||
final payload = {'action': 'set_lock', 'userId': userId, 'locked': locked};
|
||||
final accessToken = _client.auth.currentSession?.accessToken;
|
||||
final response = await _client.functions.invoke(
|
||||
'admin_user_management',
|
||||
body: payload,
|
||||
headers: accessToken == null
|
||||
? null
|
||||
: {'Authorization': 'Bearer $accessToken'},
|
||||
);
|
||||
if (response.status != 200) {
|
||||
throw Exception(response.data ?? 'Failed to update lock state');
|
||||
}
|
||||
return 'Admin request failed.';
|
||||
}
|
||||
|
||||
/// Fetch user email + banned state from the admin Edge Function (auth.user).
|
||||
Future<AdminUserStatus> fetchStatus(String userId) async {
|
||||
final payload = {'action': 'get_user', 'userId': userId};
|
||||
final accessToken = _client.auth.currentSession?.accessToken;
|
||||
final response = await _client.functions.invoke(
|
||||
'admin_user_management',
|
||||
body: payload,
|
||||
headers: accessToken == null
|
||||
? null
|
||||
: {'Authorization': 'Bearer $accessToken'},
|
||||
);
|
||||
if (response.status != 200) {
|
||||
return AdminUserStatus(email: null, bannedUntil: null);
|
||||
}
|
||||
final data = response.data;
|
||||
final user = (data is Map<String, dynamic>)
|
||||
? (data['user'] as Map<String, dynamic>?)
|
||||
: null;
|
||||
final email = user?['email'] as String?;
|
||||
DateTime? bannedUntil;
|
||||
final bannedRaw = user?['banned_until'];
|
||||
if (bannedRaw is String) {
|
||||
bannedUntil = DateTime.tryParse(bannedRaw);
|
||||
} else if (bannedRaw is DateTime) {
|
||||
bannedUntil = bannedRaw;
|
||||
}
|
||||
return AdminUserStatus(
|
||||
email: email,
|
||||
bannedUntil: bannedUntil == null ? null : AppTime.toAppTime(bannedUntil),
|
||||
);
|
||||
}
|
||||
|
||||
/// Server-side paginated listing via Edge Function (returns auth + profile light view).
|
||||
Future<List<Map<String, dynamic>>> listUsers(AdminUserQuery q) async {
|
||||
final payload = {
|
||||
'action': 'list_users',
|
||||
'offset': q.offset,
|
||||
'limit': q.limit,
|
||||
'searchQuery': q.searchQuery,
|
||||
};
|
||||
final accessToken = _client.auth.currentSession?.accessToken;
|
||||
final response = await _client.functions.invoke(
|
||||
'admin_user_management',
|
||||
body: payload,
|
||||
headers: accessToken == null
|
||||
? null
|
||||
: {'Authorization': 'Bearer $accessToken'},
|
||||
);
|
||||
if (response.status != 200) {
|
||||
throw Exception(response.data ?? 'Failed to list users');
|
||||
}
|
||||
final users = (response.data is Map && response.data['users'] is List)
|
||||
? (response.data['users'] as List).cast<Map<String, dynamic>>()
|
||||
: <Map<String, dynamic>>[];
|
||||
return users;
|
||||
}
|
||||
}
|
||||
|
||||
final adminUserStatusProvider = FutureProvider.family
|
||||
.autoDispose<AdminUserStatus, String>((ref, userId) {
|
||||
return ref.watch(adminUserControllerProvider).fetchStatus(userId);
|
||||
});
|
||||
|
||||
final adminUsersProvider =
|
||||
FutureProvider.autoDispose<List<Map<String, dynamic>>>((ref) {
|
||||
final q = ref.watch(adminUserQueryProvider);
|
||||
final ctrl = ref.watch(adminUserControllerProvider);
|
||||
return ctrl.listUsers(q);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user