Cleanup
This commit is contained in:
127
apps/web/app/admin/users/@modal/[uid]/actions.server.ts
Normal file
127
apps/web/app/admin/users/@modal/[uid]/actions.server.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
'use server';
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { withAdminSession } from '~/admin/lib/actions-utils';
|
||||
|
||||
import { Logger } from '@kit/shared/logger';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
const getClient = () => getSupabaseServerActionClient({ admin: true });
|
||||
|
||||
export const banUser = withAdminSession(async ({ userId }) => {
|
||||
await setBanDuration(userId, `876600h`);
|
||||
});
|
||||
|
||||
export const reactivateUser = withAdminSession(async ({ userId }) => {
|
||||
await setBanDuration(userId, `none`);
|
||||
});
|
||||
|
||||
export const impersonateUser = withAdminSession(async ({ userId }) => {
|
||||
await assertUserIsNotCurrentSuperAdmin(userId);
|
||||
|
||||
const client = getClient();
|
||||
|
||||
const {
|
||||
data: { user },
|
||||
error,
|
||||
} = await client.auth.admin.getUserById(userId);
|
||||
|
||||
if (error || !user) {
|
||||
throw new Error(`Error fetching user`);
|
||||
}
|
||||
|
||||
const email = user.email;
|
||||
|
||||
if (!email) {
|
||||
throw new Error(`User has no email. Cannot impersonate`);
|
||||
}
|
||||
|
||||
const { error: linkError, data } = await getClient().auth.admin.generateLink({
|
||||
type: 'magiclink',
|
||||
email,
|
||||
options: {
|
||||
redirectTo: `/`,
|
||||
},
|
||||
});
|
||||
|
||||
if (linkError || !data) {
|
||||
throw new Error(`Error generating magic link`);
|
||||
}
|
||||
|
||||
const response = await fetch(data.properties?.action_link, {
|
||||
method: 'GET',
|
||||
redirect: 'manual',
|
||||
});
|
||||
|
||||
const location = response.headers.get('Location');
|
||||
|
||||
if (!location) {
|
||||
throw new Error(`Error generating magic link. Location header not found`);
|
||||
}
|
||||
|
||||
const hash = new URL(location).hash.substring(1);
|
||||
const query = new URLSearchParams(hash);
|
||||
const accessToken = query.get('access_token');
|
||||
const refreshToken = query.get('refresh_token');
|
||||
|
||||
if (!accessToken || !refreshToken) {
|
||||
throw new Error(
|
||||
`Error generating magic link. Tokens not found in URL hash.`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken,
|
||||
refreshToken,
|
||||
};
|
||||
});
|
||||
|
||||
export const deleteUserAction = withAdminSession(
|
||||
async ({ userId }: { userId: string; csrfToken: string }) => {
|
||||
await assertUserIsNotCurrentSuperAdmin(userId);
|
||||
|
||||
Logger.info({ userId }, `Admin requested to delete user account`);
|
||||
|
||||
// we don't want to send an email to the user
|
||||
const sendEmail = false;
|
||||
|
||||
await deleteUser({
|
||||
client: getClient(),
|
||||
userId,
|
||||
sendEmail,
|
||||
});
|
||||
|
||||
revalidatePath('/admin/users', 'page');
|
||||
|
||||
Logger.info({ userId }, `User account deleted`);
|
||||
|
||||
redirect('/admin/users');
|
||||
},
|
||||
);
|
||||
|
||||
async function setBanDuration(userId: string, banDuration: string) {
|
||||
await assertUserIsNotCurrentSuperAdmin(userId);
|
||||
|
||||
await getClient().auth.admin.updateUserById(userId, {
|
||||
ban_duration: banDuration,
|
||||
});
|
||||
|
||||
revalidatePath('/admin/users');
|
||||
}
|
||||
|
||||
async function assertUserIsNotCurrentSuperAdmin(targetUserId: string) {
|
||||
const { data: user } = await getSupabaseServerActionClient().auth.getUser();
|
||||
const currentUserId = user.user?.id;
|
||||
|
||||
if (!currentUserId) {
|
||||
throw new Error(`Error fetching user`);
|
||||
}
|
||||
|
||||
if (currentUserId === targetUserId) {
|
||||
throw new Error(
|
||||
`You cannot perform a destructive action on your own account as a Super Admin`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user