hasValidRelativeSignature(), 403); abort_unless($document->isOffice() && $document->file_path, 404); return Storage::response($document->file_path); } public function callback(Request $request, Document $document): JsonResponse { abort_unless($document->isOffice(), 404); $payload = $this->verifiedPayload($request); // OnlyOffice callback statuses: 2 = ready to save, 6 = force-saved while editing. if (in_array($payload['status'] ?? null, [2, 6], true) && filled($payload['url'] ?? null)) { $response = Http::get($payload['url']); abort_unless($response->successful(), 502); Storage::put($document->file_path, $response->body()); $document->increment('current_version'); $document->update(['office_key' => Str::random(20)]); $document->versions()->create([ 'version' => $document->current_version, 'created_by' => $payload['users'][0] ?? null, ]); } return response()->json(['error' => 0]); } protected function verifiedPayload(Request $request): array { $secret = config('onlyoffice.jwt_secret'); if (blank($secret)) { return $request->all(); } $token = $request->bearerToken() ?? $request->input('token') ?? str($request->header('Authorization', ''))->after('Bearer ')->toString(); abort_if(blank($token), SymfonyResponse::HTTP_UNAUTHORIZED); $decoded = JWT::decode($token, new Key($secret, 'HS256')); return (array) ($decoded->payload ?? $decoded); } }