Skip to content

Commit

Permalink
fix: handle CORS in edge function
Browse files Browse the repository at this point in the history
  • Loading branch information
borgoat committed Nov 14, 2024
1 parent dd0fcca commit 77cafbf
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 34 deletions.
7 changes: 0 additions & 7 deletions lib/repositories/functions.dart

This file was deleted.

3 changes: 1 addition & 2 deletions lib/repositories/profiles.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class ProfilesRepository extends SupabaseRepository with Postgrest {
}

Future<void> deleteProfile() async {
await supabase.functions
.deleteAccount(supabase.auth.currentSession!.accessToken);
await supabase.functions.invoke('delete_user_account');
return table().delete().eq('id', supabase.auth.currentUser!.id);
}
}
15 changes: 13 additions & 2 deletions lib/util/config.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class __$$ConfigImplCopyWithImpl<$Res>

/// @nodoc
@JsonSerializable()
class _$ConfigImpl implements _Config {
class _$ConfigImpl with DiagnosticableTreeMixin implements _Config {
const _$ConfigImpl(
{required this.supabaseConfigPath,
required this.socialAuthWebClientId,
Expand All @@ -146,10 +146,21 @@ class _$ConfigImpl implements _Config {
final String socialAuthIosClientId;

@override
String toString() {
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
return 'Config(supabaseConfigPath: $supabaseConfigPath, socialAuthWebClientId: $socialAuthWebClientId, socialAuthIosClientId: $socialAuthIosClientId)';
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty('type', 'Config'))
..add(DiagnosticsProperty('supabaseConfigPath', supabaseConfigPath))
..add(DiagnosticsProperty('socialAuthWebClientId', socialAuthWebClientId))
..add(
DiagnosticsProperty('socialAuthIosClientId', socialAuthIosClientId));
}

@override
bool operator ==(Object other) {
return identical(this, other) ||
Expand Down
9 changes: 9 additions & 0 deletions supabase/functions/_shared/cors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// https://supabase.com/docs/guides/functions/cors

// When you're building a Supabase Function, you'll need to handle CORS headers.
// This is a common pattern for serverless functions, and it's important to ensure that your function can be invoked from a browser.
export const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"authorization, x-client-info, apikey, content-type",
};
58 changes: 35 additions & 23 deletions supabase/functions/delete_user_account/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,59 @@
// This enables autocomplete, go to definition, etc.

// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { createClient } from 'jsr:@supabase/supabase-js@2'
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from "jsr:@supabase/supabase-js@2";
import { corsHeaders } from "../_shared/cors.ts";

Deno.serve(async (req) => {
console.log(req.url)
// This is needed if you're planning to invoke your function from a browser.
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders });
}

const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
)
Deno.env.get("SUPABASE_URL") ?? "",
Deno.env.get("SUPABASE_SERVICE_ROLE_KEY") ?? "",
);

const token = req.headers.get('Authorization')?.split('Bearer ')[1]
console.log(req.headers.get('Authorization'))
const token = req.headers.get("Authorization")?.split("Bearer ")[1];
if (!token) {
return new Response(JSON.stringify({ error: 'No token provided' }), {
return new Response(JSON.stringify({ error: "No token provided" }), {
status: 401,
headers: { 'Content-Type': 'application/json' },
})
headers: { "Content-Type": "application/json" },
});
}

const { data: { user }, error: userError } = await supabase.auth.getUser(token)
const { data: { user }, error: userError } = await supabase.auth.getUser(
token,
);
if (userError || !user) {
return new Response(JSON.stringify({ error: 'Invalid token' }), {
console.error(`Failed to get user: ${userError}`);
return new Response(JSON.stringify({ error: "Invalid token" }), {
status: 401,
headers: { 'Content-Type': 'application/json' },
})
headers: { "Content-Type": "application/json" },
});
}

const { error: deleteError } = await supabase.auth.admin.deleteUser(user.id)
const { error: deleteError } = await supabase.auth.admin.deleteUser(
user.id,
);
if (deleteError) {
console.error(`Failed to delete user: ${deleteError}`);
return new Response(JSON.stringify({ error: deleteError.message }), {
status: 400,
headers: { 'Content-Type': 'application/json' },
})
headers: { "Content-Type": "application/json" },
});
}

return new Response(JSON.stringify({ message: 'User deleted successfully' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
})
})
return new Response(
JSON.stringify({ message: "User deleted successfully" }),
{
status: 200,
headers: { "Content-Type": "application/json" },
},
);
});

/* To invoke locally:
Expand Down

0 comments on commit 77cafbf

Please sign in to comment.