respond(fn () => $this->wopi->capabilities($this->tenant->requireIdentifier(), $this->identity->requireIdentifier())); } #[AuthenticatedRoute('/sessions', name: 'wopi.sessions', methods: ['POST'], permissions: ['service_wopi.view'])] public function launch(Request $request): JsonResponse { return $this->respond(function () use ($request): array { $tenant = $this->tenant->requireIdentifier(); $config = $this->wopi->configuration($tenant); // Require same-origin browser JSON POST in addition to framework authentication. if ($request->headers->get('Origin') !== $config->origin->origin || !str_starts_with(strtolower($request->headers->get('Content-Type', '')), 'application/json')) { throw new HostException('Invalid launch origin or content type.', 403); } $data = json_decode($request->getContent(), true, 32, JSON_THROW_ON_ERROR); $resource = $data['resource'] ?? null; if (!is_string($resource) || $resource === '' || strlen($resource) > 2048) { throw new HostException('A document resource is required.'); } return $this->wopi->launch($tenant, $this->identity->requireIdentifier(), $resource); }); } private function respond(callable $operation): JsonResponse { try { return new JsonResponse($operation(), 200, ['Cache-Control' => 'no-store']); } catch (HostException $error) { return new JsonResponse(['message' => $error->getMessage()], $error->status, ['Cache-Control' => 'no-store']); } catch (\JsonException) { return new JsonResponse(['message' => 'Invalid JSON request.'], 400, ['Cache-Control' => 'no-store']); } catch (\Throwable) { return new JsonResponse(['message' => 'Office viewing is temporarily unavailable.'], 503, ['Cache-Control' => 'no-store']); } } }