güncelleme
This commit is contained in:
124
lib/sms/verification-actions.ts
Normal file
124
lib/sms/verification-actions.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
"use server"
|
||||
|
||||
import { createClient } from "@/lib/supabase-server"
|
||||
import { createClient as createSupabaseClient } from "@supabase/supabase-js"
|
||||
|
||||
import { cookies } from "next/headers"
|
||||
import { NetGsmService } from "./netgsm"
|
||||
// We will reuse sendTestSms logic or create a specific one. sendTestSms uses Netgsm Service.
|
||||
// Better to export a generic 'sendSms' from lib/sms/actions.ts or just invoke the service directly.
|
||||
// lib/sms/actions.ts has `sendBulkSms` and `sendTestSms`. I should probably expose a generic `sendSms` there.
|
||||
|
||||
// Admin client for Auth Codes table access
|
||||
const supabaseAdmin = createSupabaseClient(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.SUPABASE_SERVICE_ROLE_KEY!,
|
||||
{ auth: { autoRefreshToken: false, persistSession: false } }
|
||||
)
|
||||
|
||||
export async function sendVerificationCode() {
|
||||
const supabase = createClient()
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
|
||||
if (!user) return { error: "Kullanıcı bulunamadı." }
|
||||
|
||||
// 1. Get user phone
|
||||
const { data: profile } = await supabaseAdmin
|
||||
.from('profiles')
|
||||
.select('phone')
|
||||
.eq('id', user.id)
|
||||
.single()
|
||||
|
||||
if (!profile?.phone) {
|
||||
return { error: "Profilinizde telefon numarası tanımlı değil. Lütfen yöneticinizle iletişime geçin." }
|
||||
}
|
||||
|
||||
// 2. Generate Code
|
||||
const code = Math.floor(100000 + Math.random() * 900000).toString() // 6 digit
|
||||
const expiresAt = new Date(Date.now() + 5 * 60 * 1000) // 5 mins
|
||||
|
||||
// 3. Store in DB
|
||||
// First, delete old codes for this email/user
|
||||
await supabaseAdmin.from('auth_codes').delete().eq('email', user.email!)
|
||||
|
||||
const { error: dbError } = await supabaseAdmin.from('auth_codes').insert({
|
||||
email: user.email!,
|
||||
code,
|
||||
expires_at: expiresAt.toISOString()
|
||||
})
|
||||
|
||||
if (dbError) {
|
||||
console.error("Auth code db error:", dbError)
|
||||
return { error: "Doğrulama kodu oluşturulamadı." }
|
||||
}
|
||||
|
||||
// 4. Send SMS
|
||||
// We import the logic from Netgsm service wrapper
|
||||
// Since we don't have a direct 'sendSms' export in existing actions that accepts phone/message directly without admin assertion (which we have here via admin client, but the helper function `sendTestSms` does its own checks).
|
||||
// I will use a direct call to the generic `NetgsmService` logic if I can, or modify `lib/sms/actions.ts` to export it.
|
||||
// To avoid modifying too many files, I'll instantiate NetgsmService here if I can import it, or just use `sendBulkSms` with one number?
|
||||
// `sendBulkSms` asserts admin user. But here the calling user IS logged in (but might not be admin?).
|
||||
// Actually, `sendVerificationCode` is called by the logging-in user (who might be just 'user' role).
|
||||
// `lib/sms/actions.ts` -> `assertAdmin()` checks if current user is admin.
|
||||
// So if a normal user logs in, `sendBulkSms` will fail.
|
||||
// WE NEED A SYSTEM LEVEL SEND FUNCTION.
|
||||
|
||||
// I will read credentials directly using Admin Client here.
|
||||
const { data: settings } = await supabaseAdmin.from('sms_settings').select('*').single()
|
||||
if (!settings) return { error: "SMS servisi yapılandırılmamış." }
|
||||
|
||||
// Import the class dynamically or duplicate usage?
|
||||
// The class is in `./netgsm.ts` (based on actions.ts imports).
|
||||
// Let's import { NetGsmService } from "./netgsm"
|
||||
// NetGsmService imported at top
|
||||
|
||||
const mobileService = new NetGsmService({
|
||||
username: settings.username,
|
||||
password: settings.password,
|
||||
header: settings.header,
|
||||
apiUrl: settings.api_url
|
||||
})
|
||||
|
||||
const smsResult = await mobileService.sendSms(profile.phone, `Giris Dogrulama Kodunuz: ${code}`)
|
||||
|
||||
if (!smsResult.success) {
|
||||
console.error("SMS Send Error:", smsResult)
|
||||
return { error: "SMS gönderilemedi. Lütfen daha sonra tekrar deneyin." }
|
||||
}
|
||||
|
||||
return { success: true, phone: profile.phone.slice(-4) } // Return last 4 digits
|
||||
}
|
||||
|
||||
export async function verifyCode(code: string) {
|
||||
const supabase = createClient()
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
|
||||
if (!user) return { error: "Oturum bulunamadı." }
|
||||
|
||||
// Check code
|
||||
const { data: record, error } = await supabaseAdmin
|
||||
.from('auth_codes')
|
||||
.select('*')
|
||||
.eq('email', user.email!)
|
||||
.eq('code', code)
|
||||
.gt('expires_at', new Date().toISOString())
|
||||
.single()
|
||||
|
||||
if (error || !record) {
|
||||
return { error: "Geçersiz veya süresi dolmuş kod." }
|
||||
}
|
||||
|
||||
// Success: Set Cookie
|
||||
cookies().set('parakasa_2fa_verified', 'true', {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax',
|
||||
path: '/',
|
||||
maxAge: 60 * 60 * 24 // 24 hours
|
||||
})
|
||||
|
||||
// Delete used code
|
||||
await supabaseAdmin.from('auth_codes').delete().eq('id', record.id)
|
||||
|
||||
return { success: true }
|
||||
}
|
||||
Reference in New Issue
Block a user