import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from "npm:@supabase/supabase-js@2";
// 허용할 오리진 목록
const ALLOWED_ORIGINS = [
"*" // 모든 오리진 허용 (개발 중에만 사용)
];
// CORS 헤더 설정
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': '*',
'Access-Control-Max-Age': '86400',
'Access-Control-Allow-Credentials': 'true' // 인증 정보 허용
};
// 인증 웹훅 처리 함수
Deno.serve(async (req)=>{
// CORS 프리플라이트 요청 처리
if (req.method === 'OPTIONS') {
return new Response(null, {
status: 204,
headers: corsHeaders
});
}
// 요청이 POST 메서드인지 확인
if (req.method !== 'POST') {
return new Response(JSON.stringify({
error: 'Method not allowed'
}), {
status: 405,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
try {
// 요청 본문 파싱
const bodyText = await req.text();
let payload;
try {
payload = JSON.parse(bodyText);
} catch (e) {
return new Response(JSON.stringify({
error: 'Invalid JSON'
}), {
status: 400,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// Supabase 클라이언트 초기화
const supabaseUrl = Deno.env.get('SUPABASE_URL') ?? '';
const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? '';
if (!supabaseUrl || !supabaseServiceKey) {
return new Response(JSON.stringify({
error: '서버 구성 오류: 환경 변수가 설정되지 않았습니다.'
}), {
status: 500,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
const supabase = createClient(supabaseUrl, supabaseServiceKey);
// 사용자 정보 추출
let userId, userEmail;
if (payload.user) {
userId = payload.user.id;
userEmail = payload.user.email;
} else if (payload.data) {
userId = payload.data.id;
userEmail = payload.data.email;
}
// 사용자 정보 검증
if (!userId || !userEmail) {
return new Response(JSON.stringify({
error: '사용자 정보를 찾을 수 없습니다.'
}), {
status: 400,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 사용자 이름 생성
const userName = userEmail.split('@')[0];
// users 테이블에 이미 해당 사용자가 있는지 확인
const { data: existingUser, error: fetchError } = await supabase.from('users').select('user_id').eq('user_id', userId).single();
if (fetchError && fetchError.code !== 'PGRST116') {
return new Response(JSON.stringify({
error: fetchError.message
}), {
status: 500,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 이미 사용자가 있다면 추가 작업을 하지 않음
if (existingUser) {
return new Response(JSON.stringify({
success: true,
message: '이미 등록된 사용자입니다.'
}), {
status: 200,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// public.users 테이블에 데이터 삽입
const { error: usersError } = await supabase.from('users').insert({
user_id: userId,
user_name: userName
});
if (usersError) {
return new Response(JSON.stringify({
error: usersError.message
}), {
status: 500,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// public.user_private 테이블에 데이터 삽입
const { error: userPrivateError } = await supabase.from('user_private').insert({
user_id: userId,
user_email: userEmail
});
if (userPrivateError) {
// user_private 삽입 실패 시 users 테이블 롤백
await supabase.from('users').delete().eq('user_id', userId);
return new Response(JSON.stringify({
error: userPrivateError.message
}), {
status: 500,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 성공 응답
return new Response(JSON.stringify({
success: true,
message: '사용자 등록 완료'
}), {
status: 200,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
} catch (error) {
return new Response(JSON.stringify({
error: String(error)
}), {
status: 500,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
});