snapshot()); } public function update(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $body = self::jsonBody($request); $errors = []; $changes = []; foreach (self::KEYS as $key) { if (!array_key_exists($key, $body)) { continue; } $raw = $body[$key]; if (!is_bool($raw) && !in_array($raw, [0, 1, '0', '1', 'true', 'false'], true)) { $errors[$key] = 'must be a boolean'; continue; } $value = is_bool($raw) ? $raw : in_array($raw, [1, '1', 'true'], true); $current = $this->settings->getBool($key, true); if ($current !== $value) { $changes[$key] = ['from' => $current, 'to' => $value]; } } if ($errors !== []) { return self::validationFailed($response, $errors); } if ($changes !== []) { $auditCtx = self::auditContext($request); $this->connection->transactional(function () use ($changes, $auditCtx): void { foreach ($changes as $key => $diff) { $this->settings->setBool($key, (bool) $diff['to']); } $this->audit->emitOrThrow( AuditAction::APP_SETTINGS_UPDATED, 'app_settings', null, ['changes' => $changes], $auditCtx, 'audit-toggles', ); }); } return self::json($response, 200, $this->snapshot()); } /** * @return array */ private function snapshot(): array { return [ AppSettings::KEY_AUDIT_REPORT_RECEIVED_ENABLED => $this->settings->getBool( AppSettings::KEY_AUDIT_REPORT_RECEIVED_ENABLED, true, ), AppSettings::KEY_AUDIT_BLOCKLIST_REQUEST_ENABLED => $this->settings->getBool( AppSettings::KEY_AUDIT_BLOCKLIST_REQUEST_ENABLED, true, ), ]; } }