95 lines
3.5 KiB
TypeScript
95 lines
3.5 KiB
TypeScript
import { deleteMember, handleNocoDbError, getMemberById } from '~/server/utils/nocodb';
|
|
import { createSessionManager } from '~/server/utils/session';
|
|
import { deleteKeycloakUser } from '~/server/utils/keycloak-admin';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const id = getRouterParam(event, 'id');
|
|
|
|
console.log('[api/members/[id].delete] =========================');
|
|
console.log('[api/members/[id].delete] DELETE /api/members/' + id);
|
|
console.log('[api/members/[id].delete] Request from:', getClientIP(event));
|
|
|
|
if (!id) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Member ID is required'
|
|
});
|
|
}
|
|
|
|
try {
|
|
// Validate session and require Admin privileges (delete is more sensitive)
|
|
const sessionManager = createSessionManager();
|
|
const cookieHeader = getCookie(event, 'monacousa-session') ? getHeader(event, 'cookie') : undefined;
|
|
const session = sessionManager.getSession(cookieHeader);
|
|
|
|
if (!session?.user) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: 'Authentication required'
|
|
});
|
|
}
|
|
|
|
const userTier = session.user.tier;
|
|
if (userTier !== 'admin') {
|
|
throw createError({
|
|
statusCode: 403,
|
|
statusMessage: 'Administrator privileges required to delete members'
|
|
});
|
|
}
|
|
|
|
console.log('[api/members/[id].delete] Authorized user:', session.user.email, 'Tier:', userTier);
|
|
|
|
// First, get the member data to check for Keycloak ID
|
|
let member;
|
|
try {
|
|
member = await getMemberById(id);
|
|
console.log('[api/members/[id].delete] Retrieved member for deletion:', member.first_name, member.last_name);
|
|
|
|
if (member.keycloak_id) {
|
|
console.log('[api/members/[id].delete] Member has Keycloak ID:', member.keycloak_id);
|
|
} else {
|
|
console.log('[api/members/[id].delete] Member has no Keycloak ID - NocoDB only deletion');
|
|
}
|
|
} catch (memberError: any) {
|
|
console.error('[api/members/[id].delete] Failed to retrieve member data:', memberError);
|
|
// Continue with deletion attempt even if we can't get member data
|
|
}
|
|
|
|
// If member has a Keycloak account, try to delete it first
|
|
if (member?.keycloak_id) {
|
|
try {
|
|
console.log('[api/members/[id].delete] Attempting Keycloak user deletion...');
|
|
await deleteKeycloakUser(member.keycloak_id);
|
|
console.log('[api/members/[id].delete] ✅ Keycloak user deleted successfully');
|
|
} catch (keycloakError: any) {
|
|
console.error('[api/members/[id].delete] ⚠️ Failed to delete Keycloak user:', keycloakError);
|
|
console.error('[api/members/[id].delete] Continuing with member deletion despite Keycloak failure');
|
|
// Don't throw here - we want to continue with NocoDB deletion
|
|
// This prevents orphaned NocoDB records if Keycloak is temporarily unavailable
|
|
}
|
|
}
|
|
|
|
// Delete member from NocoDB
|
|
const result = await deleteMember(id);
|
|
|
|
console.log('[api/members/[id].delete] ✅ Member deleted successfully from NocoDB:', id);
|
|
|
|
// Log completion status
|
|
if (member?.keycloak_id) {
|
|
console.log('[api/members/[id].delete] ✅ Enhanced deletion completed (NocoDB + Keycloak cleanup)');
|
|
} else {
|
|
console.log('[api/members/[id].delete] ✅ Standard deletion completed (NocoDB only)');
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: { id },
|
|
message: 'Member deleted successfully'
|
|
};
|
|
|
|
} catch (error: any) {
|
|
console.error('[api/members/[id].delete] ❌ Error deleting member:', error);
|
|
handleNocoDbError(error, 'deleteMember', 'Member');
|
|
}
|
|
});
|