Skip to content

Commit 22b6eee

Browse files
committed
feat: create a delete account route to follow apple compliance
1 parent dfc3729 commit 22b6eee

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

src/routes/profileRoutes.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import express, { Request, Response } from 'express';
2-
import { getUser, updateUser } from '../services/userService';
2+
import { getUser, updateUser, anonymizeUser } from '../services/userService';
33
import { verifyIdToken } from '../middleware/verifyIdToken';
44
import { parseMultipartForm, uploadFilesToSupabase } from '../lib/fileUpload';
55
import { deleteFile } from '../services/supabaseService';
@@ -82,5 +82,40 @@ router.get('/', verifyIdToken, async (req: Request, res: Response) => {
8282
}
8383
})
8484

85+
//for apple
86+
router.delete('/delete', verifyIdToken, async (req: Request, res: Response) => {
87+
try {
88+
const userId = req.userId;
89+
if (!userId) {
90+
res.status(401).json({ message: 'Unauthorized' });
91+
return;
92+
}
93+
94+
// Check if user exists
95+
const user = await getUser(userId);
96+
if (!user) {
97+
res.status(404).json({ message: 'User not found' });
98+
return;
99+
}
100+
101+
// Anonymize the user account
102+
const { success, error, message } = await anonymizeUser(userId);
103+
104+
if (success) {
105+
res.status(200).json({
106+
message: message || 'Account successfully deleted',
107+
details: 'Your personal information has been removed from our system'
108+
});
109+
} else {
110+
res.status(500).json({ message: error || 'Failed to delete account' });
111+
}
112+
} catch (err) {
113+
res.status(500).json({
114+
message: 'Internal Server Error',
115+
error: err instanceof Error ? err.message : err
116+
});
117+
}
118+
});
119+
85120

86121
export default router;

src/services/userService.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,4 +492,55 @@ export const createUserWithRsvpLinking = async (data: {
492492
};
493493
}
494494
}
495+
};
496+
497+
// Anonymize user account (for Apple compliance - delete account without removing data)
498+
export const anonymizeUser = async (userId: string) => {
499+
try {
500+
const user = await prisma.user.findUnique({
501+
where: { id: userId }
502+
});
503+
504+
if (!user) {
505+
return {
506+
success: false,
507+
error: 'User not found'
508+
};
509+
}
510+
511+
// Generate anonymized data
512+
const anonymizedTimestamp = Date.now();
513+
const anonymizedData = {
514+
name: `Deleted User ${anonymizedTimestamp}`,
515+
email: null,
516+
mobile_number: `deleted_${anonymizedTimestamp}_${userId.substring(0, 8)}`,
517+
profile_pic: '',
518+
verification_status: 'unverified' as VerificationStatus,
519+
gender: 'Unspecified' as Gender,
520+
};
521+
522+
// Update the user with anonymized data
523+
const anonymizedUser = await prisma.user.update({
524+
where: { id: userId },
525+
data: anonymizedData
526+
});
527+
528+
return {
529+
success: true,
530+
user: anonymizedUser,
531+
message: 'Account successfully anonymized'
532+
};
533+
} catch (error: unknown) {
534+
if (error instanceof Error) {
535+
return {
536+
success: false,
537+
error: error.message,
538+
};
539+
} else {
540+
return {
541+
success: false,
542+
error: "Failed to anonymize user account",
543+
};
544+
}
545+
}
495546
};

0 commit comments

Comments
 (0)