fix(users): refactor user admin actions to return status objects instead of throwing to prevent production error obfuscation
All checks were successful
Staging Build / build (push) Successful in 3m29s
All checks were successful
Staging Build / build (push) Successful in 3m29s
This commit is contained in:
@@ -96,12 +96,17 @@ export function UserDialog({ companies }: UserDialogProps) {
|
||||
first_name: values.first_name || undefined,
|
||||
last_name: values.last_name || undefined,
|
||||
}
|
||||
await createUser(payload)
|
||||
const res = await createUser(payload)
|
||||
if (res.success) {
|
||||
setOpen(false)
|
||||
form.reset()
|
||||
router.refresh()
|
||||
} else {
|
||||
alert(res.error || 'Fehler beim Erstellen des Benutzers.')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error creating user:', error)
|
||||
alert('Ein unerwarteter Fehler ist aufgetreten.')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,17 +63,22 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
if (confirm('Möchten Sie diesen Benutzer wirklich löschen?')) {
|
||||
setLoadingId(id)
|
||||
try {
|
||||
await deleteUser(id)
|
||||
const res = await deleteUser(id)
|
||||
if (res.success) {
|
||||
router.refresh()
|
||||
} catch (e: any) {
|
||||
console.error('Fehler beim Löschen des Benutzers:', e)
|
||||
if (e.message?.includes('Belege')) {
|
||||
} else {
|
||||
console.error('Fehler beim Löschen des Benutzers:', res.error)
|
||||
if (res.error?.includes('Belege')) {
|
||||
if (confirm('Löschen nicht möglich! Auf diesen User existieren bereits Belege. Möchten Sie diesen Benutzer stattdessen sperren?')) {
|
||||
await handleRoleChange(id, 'gesperrt')
|
||||
}
|
||||
} else {
|
||||
alert('Fehler beim Löschen: ' + (e.message || JSON.stringify(e)))
|
||||
alert('Fehler beim Löschen: ' + res.error)
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error('Fehler beim Löschen des Benutzers:', e)
|
||||
alert('Fehler beim Löschen: ' + (e.message || JSON.stringify(e)))
|
||||
} finally {
|
||||
setLoadingId(null)
|
||||
}
|
||||
@@ -83,10 +88,15 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
const handleRoleChange = async (id: string, newRole: Role) => {
|
||||
setLoadingId(id + '-role')
|
||||
try {
|
||||
await updateUserRole(id, newRole)
|
||||
const res = await updateUserRole(id, newRole)
|
||||
if (res.success) {
|
||||
router.refresh()
|
||||
} catch (e) {
|
||||
} else {
|
||||
alert(res.error || 'Fehler beim Ändern der Rolle.')
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error('Fehler beim Ändern der Rolle:', e)
|
||||
alert('Fehler beim Ändern der Rolle: ' + (e.message || JSON.stringify(e)))
|
||||
} finally {
|
||||
setLoadingId(null)
|
||||
}
|
||||
@@ -96,10 +106,15 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
const newRole = currentRole === 'gesperrt' ? 'partner' : 'gesperrt'
|
||||
setLoadingId(id + '-lock')
|
||||
try {
|
||||
await updateUserRole(id, newRole)
|
||||
const res = await updateUserRole(id, newRole)
|
||||
if (res.success) {
|
||||
router.refresh()
|
||||
} catch (e) {
|
||||
} else {
|
||||
alert(res.error || 'Fehler beim Sperren/Entsperren.')
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error('Fehler beim Sperren/Entsperren:', e)
|
||||
alert('Fehler beim Sperren/Entsperren: ' + (e.message || JSON.stringify(e)))
|
||||
} finally {
|
||||
setLoadingId(null)
|
||||
}
|
||||
@@ -241,10 +256,15 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
const val = e.target.value.trim()
|
||||
if (val !== (user.first_name || '')) {
|
||||
try {
|
||||
await updateUserProfile(user.id, { first_name: val || null, last_name: user.last_name })
|
||||
const res = await updateUserProfile(user.id, { first_name: val || null, last_name: user.last_name })
|
||||
if (res.success) {
|
||||
router.refresh()
|
||||
} catch (err) {
|
||||
} else {
|
||||
alert(res.error || 'Fehler beim Aktualisieren des Vornamens.')
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Failed to update first name:', err)
|
||||
alert('Fehler beim Aktualisieren des Vornamens: ' + (err.message || JSON.stringify(err)))
|
||||
}
|
||||
}
|
||||
}}
|
||||
@@ -263,10 +283,15 @@ export function UserList({ initialUsers, companies }: UserListProps) {
|
||||
const val = e.target.value.trim()
|
||||
if (val !== (user.last_name || '')) {
|
||||
try {
|
||||
await updateUserProfile(user.id, { first_name: user.first_name, last_name: val || null })
|
||||
const res = await updateUserProfile(user.id, { first_name: user.first_name, last_name: val || null })
|
||||
if (res.success) {
|
||||
router.refresh()
|
||||
} catch (err) {
|
||||
} else {
|
||||
alert(res.error || 'Fehler beim Aktualisieren des Nachnamens.')
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Failed to update last name:', err)
|
||||
alert('Fehler beim Aktualisieren des Nachnamens: ' + (err.message || JSON.stringify(err)))
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -50,20 +50,27 @@ export async function getUsers() {
|
||||
}
|
||||
|
||||
export async function createUser(data: { email: string; role?: 'admin' | 'partner' | 'verwaltung'; email_confirm?: boolean; company_id?: string; first_name?: string; last_name?: string }) {
|
||||
try {
|
||||
const admin = createAdminClient();
|
||||
const { data: { user }, error } = await admin.auth.admin.createUser({
|
||||
email: data.email,
|
||||
password: Math.random().toString(36).slice(-10) + Math.random().toString(36).slice(-10),
|
||||
email_confirm: data.email_confirm ?? true,
|
||||
});
|
||||
if (error) throw error;
|
||||
if (!user) throw new Error('Benutzer konnte nicht erstellt werden.');
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
if (!user) {
|
||||
return { success: false, error: 'Benutzer konnte nicht erstellt werden.' };
|
||||
}
|
||||
|
||||
const role = data.role || 'partner';
|
||||
const { error: dbError } = await admin
|
||||
.from('users')
|
||||
.upsert({ id: user.id, role, company_id: data.company_id || null }, { onConflict: 'id' });
|
||||
if (dbError) throw dbError;
|
||||
if (dbError) {
|
||||
return { success: false, error: dbError.message };
|
||||
}
|
||||
|
||||
const { error: profileError } = await admin
|
||||
.from('profiles')
|
||||
@@ -72,7 +79,9 @@ export async function createUser(data: { email: string; role?: 'admin' | 'partne
|
||||
first_name: data.first_name || null,
|
||||
last_name: data.last_name || null,
|
||||
}, { onConflict: 'id' });
|
||||
if (profileError) throw profileError;
|
||||
if (profileError) {
|
||||
return { success: false, error: profileError.message };
|
||||
}
|
||||
|
||||
// Generate recovery link to let user set password
|
||||
try {
|
||||
@@ -107,7 +116,11 @@ export async function createUser(data: { email: string; role?: 'admin' | 'partne
|
||||
}
|
||||
|
||||
revalidatePath('/admin/users');
|
||||
return user;
|
||||
return { success: true, user };
|
||||
} catch (err: any) {
|
||||
console.error('Error creating user in action:', err);
|
||||
return { success: false, error: err.message || 'Ein unerwarteter Fehler ist aufgetreten.' };
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteUser(id: string) {
|
||||
@@ -125,35 +138,44 @@ export async function deleteUser(id: string) {
|
||||
}
|
||||
|
||||
if (count && count > 0) {
|
||||
throw new Error('Auf diesen User gibt es bereits Belege. Sperren möglich.');
|
||||
return { success: false, error: 'Auf diesen User gibt es bereits Belege. Sperren möglich.' };
|
||||
}
|
||||
|
||||
// Delete from public.users first to satisfy foreign key constraints
|
||||
const { error: dbError } = await admin.from('users').delete().eq('id', id);
|
||||
if (dbError) {
|
||||
console.error('Database delete user error:', dbError);
|
||||
throw new Error(`Datenbank-Fehler beim Löschen des Benutzers: ${dbError.message}`);
|
||||
return { success: false, error: `Datenbank-Fehler beim Löschen des Benutzers: ${dbError.message}` };
|
||||
}
|
||||
|
||||
const { error } = await admin.auth.admin.deleteUser(id);
|
||||
if (error) {
|
||||
console.error('Auth delete user error:', error);
|
||||
throw new Error(`Auth-Fehler beim Löschen des Benutzers: ${error.message}`);
|
||||
return { success: false, error: `Auth-Fehler beim Löschen des Benutzers: ${error.message}` };
|
||||
}
|
||||
revalidatePath('/admin/users');
|
||||
return { success: true };
|
||||
} catch (err: any) {
|
||||
console.error('deleteUser Server Action failed:', err);
|
||||
throw new Error(err.message || 'Benutzer konnte nicht gelöscht werden.');
|
||||
return { success: false, error: err.message || 'Benutzer konnte nicht gelöscht werden.' };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateUserRole(id: string, role: 'admin' | 'partner' | 'verwaltung' | 'gesperrt') {
|
||||
try {
|
||||
const admin = createAdminClient();
|
||||
const { error } = await admin
|
||||
.from('users')
|
||||
.upsert({ id, role }, { onConflict: 'id' });
|
||||
if (error) throw error;
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
revalidatePath('/admin/users');
|
||||
return { success: true };
|
||||
} catch (err: any) {
|
||||
console.error('updateUserRole Server Action failed:', err);
|
||||
return { success: false, error: err.message || 'Rolle konnte nicht aktualisiert werden.' };
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateUserStatus(id: string, ban: boolean) {
|
||||
@@ -224,12 +246,20 @@ export async function getPartners() {
|
||||
}
|
||||
|
||||
export async function updateUserProfile(id: string, data: { first_name: string | null; last_name: string | null }) {
|
||||
try {
|
||||
const admin = createAdminClient();
|
||||
const { error } = await admin
|
||||
.from('profiles')
|
||||
.upsert({ id, first_name: data.first_name, last_name: data.last_name }, { onConflict: 'id' });
|
||||
if (error) throw error;
|
||||
if (error) {
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
revalidatePath('/admin/users');
|
||||
return { success: true };
|
||||
} catch (err: any) {
|
||||
console.error('updateUserProfile Server Action failed:', err);
|
||||
return { success: false, error: err.message || 'Profil konnte nicht aktualisiert werden.' };
|
||||
}
|
||||
}
|
||||
|
||||
function getBeautifulEmailHtml(title: string, messageHtml: string, buttonText?: string, buttonUrl?: string) {
|
||||
|
||||
Reference in New Issue
Block a user