c413004930
Dependency: - minishlink/web-push v10 (VAPID JWT + aes128gcm payload encryption) - Dockerfile: add curl, mbstring, gmp extensions (web-push needs ext-curl) VAPID: - config/webpush.php from env; `php artisan push:vapid` generates keypair - Shared platform keypair; .env.example has empty placeholders Schema: - push_subscriptions (user/company, endpoint unique, p256dh, auth, encoding) WebPushService: - send / sendToUser / dispatch via WebPush::flush - Auto-prunes subscriptions reported expired (404/410) Subscribe flow: - POST /push/subscribe + /push/unsubscribe (auth, tenant) - Tenant panel JS subscribes after SW registration with VAPID public key Service worker (/sw.js): - Cache v2, push listener → showNotification, notificationclick → focus/open Install prompt: - Floating "Instalează aplicația" button wired to beforeinstallprompt Staff push: - WorkOrder master_id change → push to assigned mechanic - Settings "Test notificare push" action Tests (6 new): - subscribe stores + upserts; requires auth (401); validation (422); service configured; sendToUser with no subs returns zero Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
45 lines
1.3 KiB
PHP
45 lines
1.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Tenant\PushSubscription;
|
|
use Illuminate\Http\Request;
|
|
|
|
class PushSubscriptionController extends Controller
|
|
{
|
|
public function subscribe(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'endpoint' => 'required|string|max:500',
|
|
'keys.p256dh' => 'required|string',
|
|
'keys.auth' => 'required|string',
|
|
'contentEncoding' => 'nullable|string|max:32',
|
|
]);
|
|
|
|
$user = $request->user();
|
|
|
|
PushSubscription::updateOrCreate(
|
|
['endpoint' => $data['endpoint']],
|
|
[
|
|
'company_id' => $user?->company_id,
|
|
'user_id' => $user?->id,
|
|
'public_key' => $data['keys']['p256dh'],
|
|
'auth_token' => $data['keys']['auth'],
|
|
'content_encoding' => $data['contentEncoding'] ?? 'aesgcm',
|
|
'user_agent' => substr((string) $request->userAgent(), 0, 255),
|
|
]
|
|
);
|
|
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
|
|
public function unsubscribe(Request $request)
|
|
{
|
|
$endpoint = $request->input('endpoint');
|
|
if ($endpoint) {
|
|
PushSubscription::where('endpoint', $endpoint)->delete();
|
|
}
|
|
return response()->json(['ok' => true]);
|
|
}
|
|
}
|