güncelleme

This commit is contained in:
2026-01-29 16:49:51 +03:00
parent 10bfa3089e
commit 54113726f4
38 changed files with 1469 additions and 642 deletions

View 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 }
}