Skip to content

Instantly share code, notes, and snippets.

@coryetzkorn
Last active August 4, 2023 04:45
Show Gist options
  • Save coryetzkorn/60eb6f8f78f36fd6662d4743556f61f3 to your computer and use it in GitHub Desktop.
Save coryetzkorn/60eb6f8f78f36fd6662d4743556f61f3 to your computer and use it in GitHub Desktop.
Delete a user's Supabase storage objects and their account
import { SupabaseBucket, SUPBABASE_BUCKETS } from "@helpers/fileHelpers"
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs"
import { createClient } from "@supabase/supabase-js"
import { cookies } from "next/headers"
import { NextRequest, NextResponse } from "next/server"
import { Database } from "../../../../types/supabase"
/**
* DELETE to:
* http://localhost:3000/api/actions/delete-account
*/
export async function DELETE(request: NextRequest) {
const supabase = createRouteHandlerClient<Database>({ cookies })
const currentUser = await supabase.auth.getUser()
const userId = currentUser?.data?.user?.id
// Make sure the user is logged in and grab the user ID
if (!userId) {
return NextResponse.json({
error: "Account cannot be deleted without an active session",
})
}
// Setup "service role" client. Required for deleting users.
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseServiceKey = process.env.SUPABASE_SERVICE_KEY
if (!supabaseUrl || !supabaseServiceKey) {
return NextResponse.json({
error: "Supabase URL or service key is missing",
})
}
const supabaseServiceClient = createClient(supabaseUrl, supabaseServiceKey, {
auth: {
persistSession: false,
autoRefreshToken: false,
detectSessionInUrl: false,
},
})
// Delete the user's storage
try {
await Promise.all(
SUPBABASE_BUCKETS.map(async (bucket: SupabaseBucket) => {
// There is no way to delete folders
// So we need to list all files and delete them one by one
const { data: fileListData, error: fileListError } =
await supabase.storage.from(bucket).list(userId)
if (fileListError) {
console.error(fileListError)
return
}
if (!fileListData?.length) return
// Perform the file deletion
const filesToRemove = fileListData.map((x) => `${userId}/${x.name}`)
const { data: deletedFileData, error: deletedFileError } =
await supabase.storage.from(bucket).remove(filesToRemove)
if (deletedFileError) {
console.error(deletedFileError)
} else {
console.log("Deleted object storage path:", bucket, deletedFileData)
}
})
)
} catch (err) {
console.error(err)
}
// Delete the user account
try {
const { data, error } = await supabaseServiceClient.auth.admin.deleteUser(
userId
)
if (error) {
console.error("Failed to delete user:", error)
return NextResponse.json({ error })
}
console.log("Deleted user account:", userId)
return NextResponse.json({ data })
} catch (error) {
console.error(error)
return NextResponse.json({ error })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment