. */ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\System; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\System\UpdateRequest; use FireflyIII\Enums\WebhookDelivery; use FireflyIII\Enums\WebhookResponse; use FireflyIII\Enums\WebhookTrigger; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Binder\EitherConfigKey; use FireflyIII\Support\Facades\FireflyConfig; use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\ValidationException; /** * Class ConfigurationController */ class ConfigurationController extends Controller { private UserRepositoryInterface $repository; /** * ConfigurationController constructor. */ public function __construct() { parent::__construct(); $this->middleware( function ($request, $next) { $this->repository = app(UserRepositoryInterface::class); return $next($request); } ); } /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getConfiguration * * @throws FireflyException */ public function index(): JsonResponse { try { $dynamicData = $this->getDynamicConfiguration(); } catch (FireflyException $e) { Log::error($e->getMessage()); Log::error($e->getTraceAsString()); throw new FireflyException('200030: Could not load config variables.', 0, $e); } $staticData = $this->getStaticConfiguration(); $return = []; foreach ($dynamicData as $key => $value) { $return[] = [ 'title' => sprintf('configuration.%s', $key), 'value' => $value, 'editable' => true, ]; } foreach ($staticData as $key => $value) { $return[] = [ 'title' => $key, 'value' => $value, 'editable' => false, ]; } return response()->api($return); } /** * Get all config values. * * @throws FireflyException */ private function getDynamicConfiguration(): array { $isDemoSite = FireflyConfig::get('is_demo_site'); $updateCheck = FireflyConfig::get('permission_update_check'); $lastCheck = FireflyConfig::get('last_update_check'); $singleUser = FireflyConfig::get('single_user_mode'); return [ 'is_demo_site' => $isDemoSite?->data, 'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, 'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data, 'single_user_mode' => $singleUser?->data, ]; } private function getStaticConfiguration(): array { $list = EitherConfigKey::$static; $return = []; foreach ($list as $key) { $return[$key] = config($key); } return $return; } /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getSingleConfiguration */ public function show(string $configKey): JsonResponse { $data = []; $dynamic = $this->getDynamicConfiguration(); $shortKey = str_replace('configuration.', '', $configKey); if (str_starts_with($configKey, 'configuration.')) { $data = [ 'title' => $configKey, 'value' => $dynamic[$shortKey], 'editable' => true, ]; return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); } if (str_starts_with($configKey, 'webhook.')) { $data = [ 'title' => $configKey, 'value' => $this->getWebhookConfiguration($configKey), 'editable' => false, ]; return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); } // fallback if (!str_starts_with($configKey, 'configuration.')) { $data = [ 'title' => $configKey, 'value' => config($configKey), 'editable' => false, ]; } return response()->api(['data' => $data])->header('Content-Type', self::JSON_CONTENT_TYPE); } /** * This endpoint is documented at: * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/setConfiguration * * Update the configuration. * * @throws FireflyException * @throws ValidationException */ public function update(UpdateRequest $request, string $name): JsonResponse { $rules = ['value' => 'required']; if (!$this->repository->hasRole(auth()->user(), 'owner')) { $messages = ['value' => '200005: You need the "owner" role to do this.']; Validator::make([], $rules, $messages)->validate(); } $data = $request->getAll(); $shortName = str_replace('configuration.', '', $name); FireflyConfig::set($shortName, $data['value']); // get updated config: $newConfig = $this->getDynamicConfiguration(); $data = [ 'title' => $name, 'value' => $newConfig[$shortName], 'editable' => true, ]; return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE); } private function getWebhookConfiguration(string $configKey): array { switch ($configKey) { case 'webhook.triggers': $cases = WebhookTrigger::cases(); $data = []; foreach ($cases as $c) { $data[$c->name] = $c->value; } return $data; case 'webhook.responses': $cases = WebhookResponse::cases(); $data = []; foreach ($cases as $c) { $data[$c->name] = $c->value; } return $data; case 'webhook.deliveries': $cases = WebhookDelivery::cases(); $data = []; foreach ($cases as $c) { $data[$c->name] = $c->value; } return $data; default: throw new FireflyException(sprintf('Unknown webhook configuration key "%s".', $configKey)); } } }