Commit f5c52da4 authored by vicotor's avatar vicotor

add new func

parent cb1ed766
......@@ -355,3 +355,14 @@ entrypoint = "./functions/sign_time_range/index.ts"
# Specifies static files to be bundled with the function. Supports glob patterns.
# For example, if you want to serve static HTML pages in your function:
# static_files = [ "./functions/sign_time_range/*.html" ]
[functions.check_sign]
enabled = true
verify_jwt = true
import_map = "./functions/check_sign/deno.json"
# Uncomment to specify a custom file path to the entrypoint.
# Supported file extensions are: .ts, .js, .mjs, .jsx, .tsx
entrypoint = "./functions/check_sign/index.ts"
# Specifies static files to be bundled with the function. Supports glob patterns.
# For example, if you want to serve static HTML pages in your function:
# static_files = [ "./functions/check_sign/*.html" ]
# Configuration for private npm package dependencies
# For more information on using private registries with Edge Functions, see:
# https://supabase.com/docs/guides/functions/import-maps#importing-from-private-registries
// supabase/functions/sign/index.ts
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { createClient } from 'jsr:@supabase/supabase-js@2';
console.log("Sign function started")
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type'
};
// Haversine公式计算距离
function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
const R = 6371 // 地球半径(千米)
const dLat = (lat2 - lat1) * Math.PI / 180
const dLon = (lon2 - lon1) * Math.PI / 180
const a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
Math.sin(dLon/2) * Math.sin(dLon/2)
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
return R * c
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response('ok', {
headers: corsHeaders
});
}
try {
// 获取用户认证信息
const authHeader = req.headers.get('Authorization');
if (!authHeader) {
console.error('no auth header')
return new Response(JSON.stringify({
error: 'No Authorization'
}), {
status: 401,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 创建Supabase客户端
const supabaseClient = createClient(Deno.env.get('SUPABASE_URL') ?? '', Deno.env.get('SUPABASE_ANON_KEY') ?? '', {
global: {
headers: {
Authorization: authHeader
}
}
});
// 获取当前用户
const { data: { user }, error: userError } = await supabaseClient.auth.getUser();
if (userError || !user) {
console.error('Auth error:', userError)
return new Response(JSON.stringify({
error: 'Auth Fail',
details: userError?.message
}), {
status: 401,
headers: {
...corsHeaders,
'Content-Type': 'application/json'
}
});
}
// 获取签到配置
const { data: config, error: configError } = await supabaseClient
.from('sign_config')
.select('*')
.order('created_at', { ascending: false })
.limit(1)
.single()
if (configError || !config) {
console.error('get sign config error:', configError)
return new Response(JSON.stringify({
success: false,
message: 'not found config'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 从 invitation 表中 获取用户信息.
const { data: userInfo, error: getError } = await supabaseClient
.from('invitation')
.select('*')
.eq('user_id', user.id)
.limit(1)
.single()
if (getError) {
console.error('Get user info error:', getError)
return new Response(JSON.stringify({
success: false,
message: 'User info fetch failed'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
if (!userInfo.in_white_list) {
// 验证时间范围
const now = new Date()
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000))
const startTime = new Date(config.start_time)
const endTime = new Date(config.end_time)
console.info(`Current Beijing time: ${beijingTime.toISOString()}, Sign time range: ${startTime.toISOString()} - ${endTime.toISOString()}`)
if (beijingTime < startTime || beijingTime > endTime) {
console.error('Not in sign time range')
return new Response(JSON.stringify({
success: false,
message: 'not in sign time range'
}), {
status: 400,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
} else {
console.info(`User ${user.id} is in the whitelist, skipping time range check.`)
}
return new Response(JSON.stringify({
success: true,
message: 'success'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
} catch (error) {
console.error('Function error:', error)
return new Response(JSON.stringify({
success: false,
message: 'Internal error'
}), {
status: 500,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
})
\ No newline at end of file
......@@ -118,23 +118,6 @@ Deno.serve(async (req) => {
})
}
// 验证时间范围
const now = new Date()
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000))
const startTime = new Date(config.start_time)
const endTime = new Date(config.end_time)
console.info(`Current Beijing time: ${beijingTime.toISOString()}, Sign time range: ${startTime.toISOString()} - ${endTime.toISOString()}`)
if (beijingTime < startTime || beijingTime > endTime) {
console.error('Not in sign time range')
return new Response(JSON.stringify({
success: false,
message: 'not in sign time range'
}), {
status: 400,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
// 从 invitation 表中 获取用户签到状态.
......@@ -146,15 +129,36 @@ Deno.serve(async (req) => {
.single()
if (getError) {
console.error('Get sign status error:', getError)
console.error('Get sign status error:', getError)
return new Response(JSON.stringify({
success: false,
message: 'User sign status fetch failed'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
if (!userInfo.in_white_list) {
// 验证时间范围
const now = new Date()
const beijingTime = new Date(now.getTime() + (8 * 60 * 60 * 1000))
const startTime = new Date(config.start_time)
const endTime = new Date(config.end_time)
console.info(`Current Beijing time: ${beijingTime.toISOString()}, Sign time range: ${startTime.toISOString()} - ${endTime.toISOString()}`)
if (beijingTime < startTime || beijingTime > endTime) {
console.error('Not in sign time range')
return new Response(JSON.stringify({
success: false,
message: 'User sign status fetch failed'
success: false,
message: 'not in sign time range'
}), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
status: 400,
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
})
}
} else {
console.info(`User ${user_id} is in the whitelist, skipping time range check`)
}
// console.log(`Fetched user info: ${JSON.stringify(userInfo)}`)
if (userInfo.is_signed) {
console.error('User has already signed in', user.id)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment