Viewing file: SettingsController.php (19.13 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request; use App\Models\UserPreference; use App\Models\NotificationSetting; use App\Models\PaymentMethod; use App\Models\PlatformFee; use App\Models\Transaction; use App\Models\RecoveryCode; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\DB; use Illuminate\Validation\Rules\Password; use Illuminate\Support\Str; use App\Models\AuditLog;
class SettingsController extends Controller { // ==================== GENERAL TAB ==================== /** * Get user profile information */ public function getProfile(Request $request) { $user = $request->user(); return response()->json([ 'name' => $user->name, 'email' => $user->email, 'type' => $user->type ?? 'customer', 'created_at' => $user->created_at->format('Y-m-d'), ]); }
/** * Update user profile */ public function updateProfile(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users,email,' . $request->user()->id, ]);
$user = $request->user(); $user->update($validated);
AuditLog::log('Profile Updated', 'settings', $user->id, $user->getChanges());
return response()->json([ 'message' => 'Profile updated successfully', 'user' => $user, ]); }
/** * Get user preferences */ public function getPreferences(Request $request) { $user = $request->user(); $preference = $user->preference ?? $user->preference()->create([ 'theme' => 'light', 'language' => 'en', 'timezone' => 'UTC', ]);
return response()->json($preference); }
/** * Update user preferences */ public function updatePreferences(Request $request) { $validated = $request->validate([ 'theme' => 'sometimes|in:light,dark', 'language' => 'sometimes|string|max:10', 'timezone' => 'sometimes|string|max:50', ]);
$user = $request->user(); $preference = $user->preference ?? $user->preference()->create(); $preference->update($validated);
AuditLog::log('Preferences Updated', 'settings', $user->id, $preference->getChanges());
return response()->json([ 'message' => 'Preferences updated successfully', 'preference' => $preference, ]); }
// ==================== NOTIFICATIONS TAB ==================== /** * Get notification settings */ public function getNotificationSettings(Request $request) { $user = $request->user(); $settings = $user->notificationSetting ?? $user->notificationSetting()->create([ 'campaign_status_updates' => true, 'budget_alerts' => true, 'low_balance_warnings' => true, 'weekly_reports' => false, 'marketing_updates' => false, 'browser_notifications' => false, ]);
return response()->json($settings); }
/** * Update notification settings */ public function updateNotificationSettings(Request $request) { $validated = $request->validate([ 'campaign_status_updates' => 'sometimes|boolean', 'budget_alerts' => 'sometimes|boolean', 'low_balance_warnings' => 'sometimes|boolean', 'weekly_reports' => 'sometimes|boolean', 'marketing_updates' => 'sometimes|boolean', 'browser_notifications' => 'sometimes|boolean', ]);
$user = $request->user(); $settings = $user->notificationSetting ?? $user->notificationSetting()->create(); $settings->update($validated);
AuditLog::log('Notification Settings Updated', 'settings', $user->id, $settings->getChanges());
return response()->json([ 'message' => 'Notification settings updated successfully', 'settings' => $settings, ]); }
// ==================== BILLING TAB ==================== /** * Get billing information */ public function getBillingInfo(Request $request) { $user = $request->user(); $wallet = $user->wallet ?? $user->wallet()->create(['balance' => 0, 'currency' => 'USD']);
return response()->json([ 'balance' => '$' . number_format($wallet->balance, 2), 'currency' => $wallet->currency, ]); }
/** * Get payment methods */ public function getPaymentMethods(Request $request) { $paymentMethods = $request->user()->paymentMethods; return response()->json($paymentMethods); }
/** * Add payment method */ public function addPaymentMethod(Request $request) { $validated = $request->validate([ 'type' => 'required|in:credit_card,bank_account', 'last_four' => 'required|string|size:4', 'expiry_month' => 'required_if:type,credit_card|integer|min:1|max:12', 'expiry_year' => 'required_if:type,credit_card|integer|min:' . date('Y'), 'provider' => 'nullable|string', 'provider_id' => 'nullable|string', ]);
$user = $request->user(); // If this is the first payment method, make it default $isFirst = $user->paymentMethods()->count() === 0; $validated['is_default'] = $isFirst;
$paymentMethod = $user->paymentMethods()->create($validated);
AuditLog::log('Payment Method Added', 'settings', $paymentMethod->id, ['type' => $paymentMethod->type, 'last_four' => $paymentMethod->last_four]);
return response()->json([ 'message' => 'Payment method added successfully', 'payment_method' => $paymentMethod, ], 201); }
/** * Delete payment method */ public function deletePaymentMethod(Request $request, $id) { $paymentMethod = $request->user()->paymentMethods()->findOrFail($id); // If deleting default, set another as default if ($paymentMethod->is_default) { $nextMethod = $request->user()->paymentMethods() ->where('id', '!=', $id) ->first(); if ($nextMethod) { $nextMethod->update(['is_default' => true]); } }
$paymentMethod->delete();
AuditLog::log('Payment Method Deleted', 'settings', $id, ['last_four' => $paymentMethod->last_four]);
return response()->json([ 'message' => 'Payment method deleted successfully', ]); }
/** * Set default payment method */ public function setDefaultPaymentMethod(Request $request, $id) { $user = $request->user(); // Remove default from all methods $user->paymentMethods()->update(['is_default' => false]); // Set new default $paymentMethod = $user->paymentMethods()->findOrFail($id); $paymentMethod->update(['is_default' => true]);
AuditLog::log('Default Payment Method Updated', 'settings', $id, ['last_four' => $paymentMethod->last_four]);
return response()->json([ 'message' => 'Default payment method updated successfully', 'payment_method' => $paymentMethod, ]); }
/** * Get invoices (transactions history) */ public function getInvoices(Request $request) { $user = $request->user(); $wallet = $user->wallet; if (!$wallet) { return response()->json([]); }
$transactions = $wallet->transactions() ->orderBy('created_at', 'desc') ->limit(50) ->get();
return response()->json($transactions); }
/** * Get fee structure */ public function getFeeStructure() { $fees = [ 'platform_markup' => PlatformFee::getActiveFee('platform_markup'), 'topup_fee' => PlatformFee::getActiveFee('topup_fee'), 'card_fee' => PlatformFee::getActiveFee('card_fee'), ];
// Format for display $feeStructure = [ 'platform_markup' => $fees['platform_markup'] ? $fees['platform_markup']->percentage . '%' : '11.5%', 'topup_fee' => $fees['topup_fee'] ? $fees['topup_fee']->percentage . '%' : '5.0%', 'card_fee' => $fees['card_fee'] ? $fees['card_fee']->percentage . '%' : '2.0%', ];
return response()->json($feeStructure); }
// ==================== SECURITY TAB ==================== /** * Get security settings */ public function getSecuritySettings(Request $request) { $user = $request->user();
return response()->json([ 'two_factor_enabled' => $user->two_factor_enabled ?? false, 'password_changed_at' => $user->password_changed_at ? $user->password_changed_at->diffForHumans() : 'Never', ]); }
/** * Setup two-factor authentication (generate QR code) */ public function setup2FA(Request $request) { $user = $request->user(); if ($user->two_factor_enabled) { return response()->json([ 'message' => '2FA is already enabled', ], 400); } // Generate Google2FA secret $google2fa = app(\PragmaRX\Google2FA\Google2FA::class); $secret = $google2fa->generateSecretKey(); // Store secret temporarily (not enabled yet) $user->update([ 'two_factor_secret' => encrypt($secret), ]); // Generate QR code $qrCodeUrl = $google2fa->getQRCodeUrl( config('app.name'), $user->email, $secret ); // Generate QR code as data URL using BaconQrCode $writer = new \BaconQrCode\Writer( new \BaconQrCode\Renderer\ImageRenderer( new \BaconQrCode\Renderer\RendererStyle\RendererStyle(200), new \BaconQrCode\Renderer\Image\SvgImageBackEnd() ) ); $qrCodeSvg = $writer->writeString($qrCodeUrl); $qrCodeDataUrl = 'data:image/svg+xml;base64,' . base64_encode($qrCodeSvg); return response()->json([ 'secret' => $secret, 'qr_code_url' => $qrCodeDataUrl, ]); }
/** * Verify and enable two-factor authentication */ public function verify2FASetup(Request $request) { $validated = $request->validate([ 'code' => 'required|string|size:6', ]); $user = $request->user(); if ($user->two_factor_enabled) { return response()->json([ 'message' => '2FA is already enabled', ], 400); } if (!$user->two_factor_secret) { return response()->json([ 'message' => 'Please setup 2FA first', ], 400); } // Verify the code $google2fa = app(\PragmaRX\Google2FA\Google2FA::class); $secret = decrypt($user->two_factor_secret); $valid = $google2fa->verifyKey($secret, $validated['code']); if (!$valid) { return response()->json([ 'message' => 'Invalid verification code', ], 422); } // Enable 2FA $user->update([ 'two_factor_enabled' => true, ]); // Generate recovery codes $recoveryCodes = $this->generateRecoveryCodes($user); AuditLog::log('2FA Enabled', 'security', $user->id, []);
return response()->json([ 'message' => '2FA enabled successfully', 'recovery_codes' => $recoveryCodes, ]); }
/** * Disable two-factor authentication */ public function disableTwoFactor(Request $request) { $validated = $request->validate([ 'code' => 'required|string|size:6', ]); $user = $request->user(); if (!$user->two_factor_enabled) { return response()->json([ 'message' => '2FA is not enabled', ], 400); } // Verify the code before disabling $google2fa = app(\PragmaRX\Google2FA\Google2FA::class); $secret = decrypt($user->two_factor_secret); $valid = $google2fa->verifyKey($secret, $validated['code']); if (!$valid) { return response()->json([ 'message' => 'Invalid verification code', ], 422); } $user->update([ 'two_factor_enabled' => false, 'two_factor_secret' => null, ]);
AuditLog::log('2FA Disabled', 'security', $user->id, []);
return response()->json([ 'message' => '2FA disabled successfully', ]); }
/** * Generate recovery codes for a user */ private function generateRecoveryCodes($user, $count = 10) { // Delete existing recovery codes $user->recoveryCodes()->delete(); // Generate new codes $plainCodes = []; $hashedCodes = []; for ($i = 0; $i < $count; $i++) { $code = strtoupper(Str::random(4) . '-' . Str::random(4)); $plainCodes[] = $code; $hashedCodes[] = [ 'user_id' => $user->id, 'code' => Hash::make($code), 'created_at' => now(), 'updated_at' => now(), ]; } RecoveryCode::insert($hashedCodes); return $plainCodes; }
/** * Get recovery codes */ public function getRecoveryCodes(Request $request) { $user = $request->user(); if (!$user->two_factor_enabled) { return response()->json([ 'message' => '2FA is not enabled', ], 400); } $codes = $user->recoveryCodes()->get()->map(function ($code) { return [ 'id' => $code->id, 'used' => !is_null($code->used_at), 'used_at' => $code->used_at?->format('Y-m-d H:i:s'), 'created_at' => $code->created_at->format('Y-m-d H:i:s'), ]; }); return response()->json([ 'codes' => $codes, 'total' => $codes->count(), 'unused' => $codes->where('used', false)->count(), ]); }
/** * Regenerate recovery codes */ public function regenerateRecoveryCodes(Request $request) { $validated = $request->validate([ 'code' => 'required|string|size:6', ]); $user = $request->user(); if (!$user->two_factor_enabled) { return response()->json([ 'message' => '2FA is not enabled', ], 400); } // Verify 2FA code $google2fa = app(\PragmaRX\Google2FA\Google2FA::class); $secret = decrypt($user->two_factor_secret); $valid = $google2fa->verifyKey($secret, $validated['code']); if (!$valid) { return response()->json([ 'message' => 'Invalid verification code', ], 422); } // Generate new recovery codes $recoveryCodes = $this->generateRecoveryCodes($user); return response()->json([ 'message' => 'Recovery codes regenerated successfully', 'recovery_codes' => $recoveryCodes, ]); }
/** * Change password */ public function changePassword(Request $request) { $validated = $request->validate([ 'current_password' => 'required', 'new_password' => ['required', 'confirmed', Password::min(8)], ]);
$user = $request->user();
// Verify current password if (!Hash::check($validated['current_password'], $user->password)) { return response()->json([ 'message' => 'Current password is incorrect', ], 422); }
$user->update([ 'password' => Hash::make($validated['new_password']), 'password_changed_at' => now(), ]);
AuditLog::log('Password Changed', 'security', $user->id, []);
return response()->json([ 'message' => 'Password changed successfully', ]); }
/** * Get active sessions */ public function getActiveSessions(Request $request) { // Get sessions from database $sessions = DB::table('sessions') ->where('user_id', $request->user()->id) ->orderBy('last_activity', 'desc') ->get() ->map(function ($session) { return [ 'id' => $session->id, 'ip_address' => $session->ip_address, 'user_agent' => $session->user_agent, 'last_activity' => date('Y-m-d H:i:s', $session->last_activity), ]; });
return response()->json($sessions); }
/** * Revoke a session */ public function revokeSession(Request $request, $sessionId) { DB::table('sessions') ->where('id', $sessionId) ->where('user_id', $request->user()->id) ->delete();
AuditLog::log('Session Revoked', 'security', $request->user()->id, ['session_id' => $sessionId]);
return response()->json([ 'message' => 'Session revoked successfully', ]); }
/** * Download account data */ public function downloadAccountData(Request $request) { $user = $request->user()->load([ 'campaigns', 'wallet.transactions', 'preference', 'notificationSetting', 'paymentMethods', ]);
$data = [ 'user' => $user->only(['name', 'email', 'type', 'created_at']), 'campaigns' => $user->campaigns, 'wallet' => $user->wallet, 'transactions' => $user->wallet ? $user->wallet->transactions : [], 'preferences' => $user->preference, 'notification_settings' => $user->notificationSetting, 'payment_methods' => $user->paymentMethods->map(function ($pm) { return $pm->only(['type', 'last_four', 'expiry_month', 'expiry_year']); }), ];
return response()->json($data); }
/** * Request account deletion */ public function requestAccountDeletion(Request $request) { $user = $request->user(); $user->update([ 'account_deletion_requested_at' => now(), ]);
AuditLog::log('Account Deletion Requested', 'security', $user->id, []);
// In production, send email notification and schedule deletion return response()->json([ 'message' => 'Account deletion requested. You will receive a confirmation email.', ]); } }
|