From 453592b5add15bda842f8f0e3fd738ed4c25f609 Mon Sep 17 00:00:00 2001 From: Daffa Aditya Rejasa Ruswanto Date: Tue, 28 Apr 2026 16:29:07 +0700 Subject: [PATCH] migration to pusher --- .codex | 0 .../Controllers/Mobile/AbsenController.php | 29 +++++++++++++++++-- config/broadcasting.php | 19 +++++------- .../landing/components/features.blade.php | 12 ++++---- resources/views/qrcode/qr-page.blade.php | 11 +++---- routes/web.php | 19 ++++++------ 6 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 .codex diff --git a/.codex b/.codex new file mode 100644 index 0000000..e69de29 diff --git a/app/Http/Controllers/Mobile/AbsenController.php b/app/Http/Controllers/Mobile/AbsenController.php index b2840af..4be6865 100644 --- a/app/Http/Controllers/Mobile/AbsenController.php +++ b/app/Http/Controllers/Mobile/AbsenController.php @@ -13,6 +13,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Validator; class AbsenController extends Controller { @@ -23,13 +24,35 @@ private function qrTtl(): int public function verify(Request $req, DynamicQrService $svc) { - $req->validate([ + $req->merge([ + 'latitude' => $req->filled('latitude') + ? str_replace(',', '.', (string) $req->input('latitude')) + : $req->input('latitude'), + 'longitude' => $req->filled('longitude') + ? str_replace(',', '.', (string) $req->input('longitude')) + : $req->input('longitude'), + ]); + + $validator = Validator::make($req->all(), [ 'token' => 'required|string', 'user_id' => 'required|integer', 'device_info' => 'nullable|string', - 'latitude' => 'nullable|numeric|between:-90,90', - 'longitude' => 'nullable|numeric|between:-180,180', + 'latitude' => 'required|numeric|between:-90,90', + 'longitude' => 'required|numeric|between:-180,180', + ], [ + 'latitude.numeric' => 'Latitude harus berupa angka yang valid.', + 'latitude.between' => 'Latitude harus berada di antara -90 sampai 90.', + 'longitude.numeric' => 'Longitude harus berupa angka yang valid.', + 'longitude.between' => 'Longitude harus berada di antara -180 sampai 180.', ]); + + if ($validator->fails()) { + return response()->json([ + 'ok' => false, + 'reason' => 'validation_error', + 'errors' => $validator->errors(), + ], 422); + } $lat = $req->input('latitude'); $lng = $req->input('longitude'); diff --git a/config/broadcasting.php b/config/broadcasting.php index 7ba92d0..e3ec2e1 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -31,20 +31,17 @@ 'connections' => [ 'pusher' => [ - 'driver' => 'pusher', - 'key' => env('PUSHER_APP_KEY'), - 'secret' => env('PUSHER_APP_SECRET'), - 'app_id' => env('PUSHER_APP_ID'), + 'driver' => 'pusher', + 'key' => env('PUSHER_APP_KEY'), + 'secret' => env('PUSHER_APP_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), 'options' => [ - // Pakai cluster hosted Pusher (contoh: ap1) 'cluster' => env('PUSHER_APP_CLUSTER'), - // Force TLS utk hosted Pusher - 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', - - // Opsi custom host/port (kosongkan jika pakai hosted Pusher) - 'host' => env('PUSHER_HOST'), - 'port' => env('PUSHER_PORT', 443), + 'useTLS' => true, + 'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'ap1') . '.pusher.com', + 'port' => env('PUSHER_PORT', 443), 'scheme' => env('PUSHER_SCHEME', 'https'), + 'encrypted' => true, ], ], diff --git a/resources/views/landing/components/features.blade.php b/resources/views/landing/components/features.blade.php index b339c07..44b021a 100644 --- a/resources/views/landing/components/features.blade.php +++ b/resources/views/landing/components/features.blade.php @@ -315,14 +315,12 @@ function patchAttendanceRow(update) { // init Echo Reverb window.Pusher = window.Pusher || Pusher; + const echo = new window.Echo({ - broadcaster: 'reverb', - key: "{{ env('REVERB_APP_KEY') }}", - wsHost: "{{ env('REVERB_HOST', '127.0.0.1') }}", - wsPort: {{ env('REVERB_PORT', 8080) }}, - wssPort: {{ env('REVERB_PORT', 8080) }}, - forceTLS: "{{ env('REVERB_SCHEME', 'http') }}" === 'https', - enabledTransports: ['ws', 'wss'], + broadcaster: 'pusher', + key: "{{ env('PUSHER_APP_KEY') }}", + cluster: "{{ env('PUSHER_APP_CLUSTER', 'ap1') }}", + forceTLS: "{{ env('PUSHER_SCHEME', 'https') }}" === 'https', }); echo.channel('attendance.global') diff --git a/resources/views/qrcode/qr-page.blade.php b/resources/views/qrcode/qr-page.blade.php index 57ad4af..68ee7e6 100644 --- a/resources/views/qrcode/qr-page.blade.php +++ b/resources/views/qrcode/qr-page.blade.php @@ -529,13 +529,10 @@ function initializeEcho() { window.Pusher = window.Pusher || Pusher; const echo = new window.Echo({ - broadcaster: 'reverb', - key: "{{ env('REVERB_APP_KEY') }}", - wsHost: "{{ env('REVERB_HOST', '127.0.0.1') }}", - wsPort: {{ env('REVERB_PORT', 8080) }}, - wssPort: {{ env('REVERB_PORT', 8080) }}, - forceTLS: "{{ env('REVERB_SCHEME', 'http') }}" === 'https', - enabledTransports: ['ws', 'wss'], + broadcaster: 'pusher', + key: "{{ env('PUSHER_APP_KEY') }}", + cluster: "{{ env('PUSHER_APP_CLUSTER', 'ap1') }}", + forceTLS: "{{ env('PUSHER_SCHEME', 'https') }}" === 'https', }); window.echo = echo; // untuk debug diff --git a/routes/web.php b/routes/web.php index 2937f8a..b33b380 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,7 +14,6 @@ Route::get('/', [LandingPageController::class, 'index'])->name('home'); // Auth Routes - Route::get('/login', [AuthController::class, 'showLoginForm'])->name('login'); Route::post('/login', [AuthController::class, 'login']); Route::get('/forgot-password', [AuthController::class, 'showForgetPasswordForm'])->name('forget.password'); @@ -29,6 +28,15 @@ Route::get('/news/{slug}', [NewsController::class, 'show'])->name('news.show'); Route::get('/api/news/categories', [NewsController::class, 'getCategories'])->name('news.categories'); +Route::get('/attendance/sessions/{sessionId}', [AttendanceController::class, 'showPage']) + ->name('attendance.session.show'); +Route::get('/admin/attendance/sessions/{sessionId}/qrcode', [AttendanceController::class, 'currentToken']) + ->name('admin.attendance.session.qrcode'); +Route::get('/admin/attendance/sessions/{sessionId}/members', [AttendanceController::class, 'members']) + ->name('admin.attendance.session.members'); +Route::post('/admin/attendance/sessions/{sessionId}/rotate', [AttendanceController::class, 'forceRotate']) + ->name('admin.attendance.session.rotate'); + // Admin routes /* |-------------------------------------------------------------------------- @@ -95,12 +103,3 @@ Route::get('/logout', [AuthController::class, 'logout'])->name('logout'); }); - -Route::get('/attendance/sessions/{sessionId}', [AttendanceController::class, 'showPage']) - ->name('attendance.session.show'); -Route::get('/admin/attendance/sessions/{sessionId}/qrcode', [AttendanceController::class, 'currentToken']) - ->name('admin.attendance.session.qrcode'); -Route::get('/admin/attendance/sessions/{sessionId}/members', [AttendanceController::class, 'members']) - ->name('admin.attendance.session.members'); -Route::post('/admin/attendance/sessions/{sessionId}/rotate', [AttendanceController::class, 'forceRotate']) - ->name('admin.attendance.session.rotate');