Skip to content

Commit b06b4ea

Browse files
authored
Delete user edge function (#2829)
* feat: create oauth client utilities for mining-sources edge function * fix: address code review issues - pin deps, add guards, fix types * feat: create mining-sources edge function with OAuth routes * fix: address code review issues - add onError handler, fix credentials JSON, add getRequiredEnv * test: add tests for mining-sources utility functions and route schemas * test: extract schemas to shared module, strengthen test assertions, add edge cases * feat: update frontend to call mining-sources edge function * chore: remove deprecated Express OAuth routes and methods * chore: remove deprecated add-mining-source edge function (replaced by mining-sources) * test: remove deprecated OAuth helper tests (functionality moved to edge function) * fix: resolve CI lint and DeepSource issues * feat: make oauth_callback_base_url a required env var with no fallbacks * docs: mark oauth_callback_base_url as required in env template * feat: add mining-sources config and document oauth_callback_base_url env var * fix: hmac-sign oauth state to prevent userId forgery * feat: add callbackQuerySchema for oauth callback route validation * test: add callbackQuerySchema tests * feat: use zod validation for oauth callback route params * chore: remove orphaned validator schemas and stale add-mining-source directory * fix: remove dead OAuth code from mining controller (post-merge cleanup) * feat: add create_smtp_sender_for_oauth rpc for smtp twin creation * feat: add smtp twin creation to mining-sources edge function callback * test: add smtp twin creation tests for mining-sources edge function * chore: remove plan docs from remote * chore: remove workmux config from remote * fix: use const instead of let for accessToken/refreshToken (deepsource) * feat: create delete-user edge function Move user account deletion from Express backend to a new Supabase edge function. The edge function verifies the user via JWT, calls the delete_user_data RPC, then deletes the auth user via admin API. Closes #2810 * feat(frontend): call delete-user edge function from settings Replace direct Express API call ($api) with the new delete-user edge function ($saasEdgeFunctions) for account deletion. * refactor(backend): remove Express delete-user code The auth controller, user resolver interface and implementation, and related wiring (auth routes, app, server) are no longer needed since the delete-user edge function handles account deletion. * fix(delete-user): pass JWT explicitly to auth.getUser() The default auth.getUser() call has a known issue where it may return null user data when called from an Edge Function with no Supabase session. Pass the JWT explicitly to avoid silently 401ing real users. Also drop the unused getRequiredEnv import. * fix(delete-user): explicit return on authMiddleware to satisfy DeepSource JS-0045
1 parent 4b3cef2 commit b06b4ea

12 files changed

Lines changed: 238 additions & 164 deletions

File tree

backend/src/app.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ENV from './config';
88
import { Contacts } from './db/interfaces/Contacts';
99
import { MiningSources } from './db/interfaces/MiningSources';
1010
import { SmtpSenders } from './db/interfaces/SmtpSenders';
11-
import { Users } from './db/interfaces/Users';
11+
1212
import corsMiddleware from './middleware/cors';
1313
import errorHandler from './middleware/errorHandler';
1414
import errorLogger from './middleware/errorLogger';
@@ -32,7 +32,7 @@ export default function initializeApp(
3232
miningEngine: MiningEngine,
3333
miningSources: MiningSources,
3434
contacts: Contacts,
35-
userResolver: Users,
35+
3636
logger: Logger,
3737
miningControllerDeps: MiningControllerDeps,
3838
smtpSenders: SmtpSenders
@@ -62,7 +62,7 @@ export default function initializeApp(
6262
res.json({ message: 'Welcome to leadminer application.' })
6363
);
6464

65-
app.use('/api/auth', initializeAuthRoutes(authResolver, userResolver));
65+
app.use('/api/auth', initializeAuthRoutes());
6666
app.use('/api/imap', initializeImapRoutes(authResolver, miningSourceService));
6767
app.use('/api/imap', initializeStreamRouter(miningEngine, authResolver));
6868
app.use(

backend/src/controllers/auth.controller.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

backend/src/db/interfaces/Users.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

backend/src/db/supabase/users.ts

Lines changed: 0 additions & 87 deletions
This file was deleted.

backend/src/routes/auth.routes.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
11
import { Router } from 'express';
2-
import { Users } from '../db/interfaces/Users';
3-
import initializeAuthController from '../controllers/auth.controller';
4-
import initializeAuthMiddleware from '../middleware/auth';
5-
import AuthResolver from '../services/auth/AuthResolver';
62

7-
export default function initializeAuthRoutes(
8-
authResolver: AuthResolver,
9-
userResolver: Users
10-
) {
3+
export default function initializeAuthRoutes() {
114
const router = Router();
12-
const middleware = initializeAuthMiddleware(authResolver);
13-
const { deleteUserAccount } = initializeAuthController(userResolver);
14-
15-
router.delete('/users', middleware, deleteUserAccount);
165

176
return router;
187
}

backend/src/server.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import PgContacts from './db/pg/PgContacts';
77
import PgMiningSources from './db/pg/PgMiningSources';
88
import PgSmtpSenders from './db/pg/PgSmtpSenders';
99
import SupabaseTasks from './db/supabase/tasks';
10-
import SupabaseUsers from './db/supabase/users';
10+
1111
import SupabaseAuthResolver from './services/auth/SupabaseAuthResolver';
1212
import EmailFetcherClient from './services/email-fetching';
1313
import PSTFetcherClient from './services/email-fetching/pst';
@@ -47,7 +47,7 @@ console.log(
4747
);
4848
const authResolver = new SupabaseAuthResolver(supabaseClient, logger);
4949
const contactsResolver = new PgContacts(pool, logger);
50-
const userResolver = new SupabaseUsers(supabaseClient, logger);
50+
5151
const tasksResolver = new SupabaseTasks(supabaseClient, logger);
5252
const miningEngine = new MiningEngine({
5353
redisSubscriber: redis.getSubscriberClient()
@@ -80,7 +80,6 @@ console.log(
8080
miningEngine,
8181
miningSources,
8282
contactsResolver,
83-
userResolver,
8483
logger,
8584
miningControllerDeps,
8685
smtpSenders

frontend/src/pages/account/settings.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ const { t: $t } = useI18n({
171171
});
172172
173173
const $toast = useToast();
174-
const { $api } = useNuxtApp();
174+
const { $saasEdgeFunctions } = useNuxtApp();
175175
const $profile = useSupabaseUserProfile();
176176
177177
const {
@@ -316,7 +316,7 @@ async function updateUserDetailsButton() {
316316
async function deleteAccount() {
317317
isLoading.value = true;
318318
try {
319-
await $api('/auth/users', {
319+
await $saasEdgeFunctions('delete-user', {
320320
method: 'DELETE',
321321
});
322322
signOutManually({

supabase/functions/add-mining-source/deno.json

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"imports": {
3+
"hono": "https://esm.sh/hono@4.7.4"
4+
}
5+
}

supabase/functions/delete-user/deno.lock

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)