From 9c821e24800ae979a2ef8deff52788376bf38654 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Sat, 6 Jul 2024 14:34:15 +0200 Subject: [PATCH] init openapi generator --- app/Http/Controllers/Api/OpenApi.php | 39 ++- app/Http/Controllers/Api/OtherController.php | 187 +++++++++++ app/Http/Controllers/Api/TeamController.php | 90 +++-- app/Models/Team.php | 53 +++ openapi.yaml | 330 +++++++++++++++++-- routes/api.php | 54 +-- 6 files changed, 653 insertions(+), 100 deletions(-) create mode 100644 app/Http/Controllers/Api/OtherController.php diff --git a/app/Http/Controllers/Api/OpenApi.php b/app/Http/Controllers/Api/OpenApi.php index 0878238f0..e52c47ccb 100644 --- a/app/Http/Controllers/Api/OpenApi.php +++ b/app/Http/Controllers/Api/OpenApi.php @@ -5,8 +5,43 @@ use OpenApi\Attributes as OA; #[OA\Info(title: 'Coolify', version: '0.1')] -#[OA\Server(url: 'https://coolify.io/api/v1')] -#[OA\SecurityScheme(type: 'http', scheme: 'bearer', bearerFormat: 'JWT', securityScheme: 'bearerAuth')] +#[OA\Server(url: 'https://app.coolify.io/api/v1')] +#[OA\SecurityScheme( + type: 'http', + scheme: 'bearer', + securityScheme: 'bearerAuth', + description: 'Go to `Keys & Tokens` / `API tokens` and create a new token. Use the token as the bearer token.')] +#[OA\Components( + responses: [ + new OA\Response( + response: 401, + description: 'Unauthenticated.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'Unauthenticated.'), + ] + )), + new OA\Response( + response: 400, + description: 'Invalid token.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'Invalid token.'), + ] + )), + new OA\Response( + response: 404, + description: 'Resource not found.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string'), + ] + )), + ], +)] class OpenApi { // This class is used to generate OpenAPI documentation diff --git a/app/Http/Controllers/Api/OtherController.php b/app/Http/Controllers/Api/OtherController.php new file mode 100644 index 000000000..7ec7d8dd5 --- /dev/null +++ b/app/Http/Controllers/Api/OtherController.php @@ -0,0 +1,187 @@ + []], + ], + responses: [ + new OA\Response( + response: 200, + description: 'Returns the version of the application', + content: new OA\JsonContent( + type: 'string', + example: 'v4.0.0', + )), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + ] + )] + public function version(Request $request) + { + return response(config('version')); + } + + #[OA\Get( + summary: 'Enable API', + description: 'Enable API (only with root permissions).', + path: '/enable', + security: [ + ['bearerAuth' => []], + ], + responses: [ + new OA\Response( + response: 200, + description: 'Enable API.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'API enabled.'), + ] + )), + new OA\Response( + response: 403, + description: 'You are not allowed to enable the API.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'You are not allowed to enable the API.'), + ] + )), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + ] + )] + public function enable_api(Request $request) + { + $teamId = getTeamIdFromToken(); + if (is_null($teamId)) { + return invalidTokenResponse(); + } + if ($teamId !== '0') { + return response()->json(['message' => 'You are not allowed to enable the API.'], 403); + } + $settings = InstanceSettings::get(); + $settings->update(['is_api_enabled' => true]); + + return response()->json(['message' => 'API enabled.'], 200); + } + + #[OA\Get( + summary: 'Disable API', + description: 'Disable API (only with root permissions).', + path: '/disable', + security: [ + ['bearerAuth' => []], + ], + responses: [ + new OA\Response( + response: 200, + description: 'Disable API.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'API disabled.'), + ] + )), + new OA\Response( + response: 403, + description: 'You are not allowed to disable the API.', + content: new OA\JsonContent( + type: 'object', + properties: [ + new OA\Property(property: 'message', type: 'string', example: 'You are not allowed to disable the API.'), + ] + )), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + ] + )] + public function disable_api(Request $request) + { + $teamId = getTeamIdFromToken(); + if (is_null($teamId)) { + return invalidTokenResponse(); + } + if ($teamId !== '0') { + return response()->json(['message' => 'You are not allowed to disable the API.'], 403); + } + $settings = InstanceSettings::get(); + $settings->update(['is_api_enabled' => false]); + + return response()->json(['message' => 'API disabled.'], 200); + } + + public function feedback(Request $request) + { + $content = $request->input('content'); + $webhook_url = config('coolify.feedback_discord_webhook'); + if ($webhook_url) { + Http::post($webhook_url, [ + 'content' => $content, + ]); + } + + return response()->json(['message' => 'Feedback sent.'], 200); + } + + #[OA\Get( + summary: 'Healthcheck', + description: 'Healthcheck endpoint.', + path: '/healthcheck', + security: [ + ['bearerAuth' => []], + ], + responses: [ + new OA\Response( + response: 200, + description: 'Healthcheck endpoint.', + content: new OA\JsonContent( + type: 'string', + example: 'OK', + )), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + ] + )] + public function healthcheck(Request $request) + { + return 'OK'; + } +} diff --git a/app/Http/Controllers/Api/TeamController.php b/app/Http/Controllers/Api/TeamController.php index 32863aff3..e155ad1b7 100644 --- a/app/Http/Controllers/Api/TeamController.php +++ b/app/Http/Controllers/Api/TeamController.php @@ -28,9 +28,37 @@ private function removeSensitiveData($team) return serializeApiResponse($team); } - #[OA\Get(path: '/teams')] - #[OA\Response(response: '200', description: 'List of teams')] - #[OA\Response(response: '401', description: 'Unauthorized')] + #[OA\Get( + summary: 'List', + description: 'Get all teams.', + path: '/teams', + security: [ + ['bearerAuth' => []], + ], + tags: ['Teams'], + responses: [ + new OA\Response( + response: 200, + description: 'List of teams.', + content: [ + new OA\MediaType( + mediaType: 'application/json', + schema: new OA\Schema( + type: 'array', + items: new OA\Items(ref: '#/components/schemas/Team') + ) + ), + ]), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + ] + )] public function teams(Request $request) { $teamId = getTeamIdFromToken(); @@ -47,32 +75,36 @@ public function teams(Request $request) ); } - #[OA\Get(path: '/teams/{id}')] - #[OA\Response( - response: 401, - description: 'Unauthorized', - content: new OA\JsonContent( - type: 'object', - properties: [ - new OA\Property(property: 'message', type: 'string', example: 'Unauthenticated.'), - ] - ) - )] - #[OA\Response(response: '404', description: 'Team not found')] - #[OA\Parameter(name: 'id', in: 'path', required: true, description: 'Team ID', schema: new OA\Schema(type: 'integer'))] - // response 200 with team model - #[OA\Response( - response: 200, - description: 'Team model', - content: new OA\JsonContent( - type: 'object', - properties: [ - new OA\Property(property: 'id', type: 'integer', example: 1), - new OA\Property(property: 'name', type: 'string', example: 'Team 1'), - new OA\Property(property: 'created_at', type: 'string', format: 'date-time', example: '2021-10-10T10:00:00Z'), - new OA\Property(property: 'updated_at', type: 'string', format: 'date-time', example: '2021-10-10T10:00:00Z'), - ] - ) + #[OA\Get( + summary: 'Get', + description: 'Get team by TeamId.', + path: '/teams/{id}', + security: [ + ['bearerAuth' => []], + ], + tags: ['Teams'], + parameters: [ + new OA\Parameter(name: 'id', in: 'path', required: true, description: 'Team ID', schema: new OA\Schema(type: 'integer')), + ], + responses: [ + new OA\Response( + response: 200, + description: 'List of teams.', + content: new OA\JsonContent(ref: '#/components/schemas/Team') + ), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + new OA\Response( + response: 404, + ref: '#/components/responses/404', + ), + ] )] public function team_by_id(Request $request) { diff --git a/app/Models/Team.php b/app/Models/Team.php index fe5995a1b..8b8c472ee 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -7,7 +7,60 @@ use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; +use OpenApi\Attributes as OA; +#[OA\Schema( + description: 'Team model', + type: 'object', + properties: [ + 'id' => ['type' => 'integer', 'description' => 'The unique identifier of the team.'], + 'name' => ['type' => 'string', 'description' => 'The name of the team.'], + 'description' => ['type' => 'string', 'description' => 'The description of the team.'], + 'personal_team' => ['type' => 'boolean', 'description' => 'Whether the team is personal or not.'], + 'created_at' => ['type' => 'string', 'description' => 'The date and time the team was created.'], + 'updated_at' => ['type' => 'string', 'description' => 'The date and time the team was last updated.'], + 'smtp_enabled' => ['type' => 'boolean', 'description' => 'Whether SMTP is enabled or not.'], + 'smtp_from_address' => ['type' => 'string', 'description' => 'The email address to send emails from.'], + 'smtp_from_name' => ['type' => 'string', 'description' => 'The name to send emails from.'], + 'smtp_recipients' => ['type' => 'string', 'description' => 'The email addresses to send emails to.'], + 'smtp_host' => ['type' => 'string', 'description' => 'The SMTP host.'], + 'smtp_port' => ['type' => 'string', 'description' => 'The SMTP port.'], + 'smtp_encryption' => ['type' => 'string', 'description' => 'The SMTP encryption.'], + 'smtp_username' => ['type' => 'string', 'description' => 'The SMTP username.'], + 'smtp_password' => ['type' => 'string', 'description' => 'The SMTP password.'], + 'smtp_timeout' => ['type' => 'string', 'description' => 'The SMTP timeout.'], + 'smtp_notifications_test' => ['type' => 'boolean', 'description' => 'Whether to send test notifications via SMTP.'], + 'smtp_notifications_deployments' => ['type' => 'boolean', 'description' => 'Whether to send deployment notifications via SMTP.'], + 'smtp_notifications_status_changes' => ['type' => 'boolean', 'description' => 'Whether to send status change notifications via SMTP.'], + 'smtp_notifications_scheduled_tasks' => ['type' => 'boolean', 'description' => 'Whether to send scheduled task notifications via SMTP.'], + 'smtp_notifications_database_backups' => ['type' => 'boolean', 'description' => 'Whether to send database backup notifications via SMTP.'], + 'discord_enabled' => ['type' => 'boolean', 'description' => 'Whether Discord is enabled or not.'], + 'discord_webhook_url' => ['type' => 'string', 'description' => 'The Discord webhook URL.'], + 'discord_notifications_test' => ['type' => 'boolean', 'description' => 'Whether to send test notifications via Discord.'], + 'discord_notifications_deployments' => ['type' => 'boolean', 'description' => 'Whether to send deployment notifications via Discord.'], + 'discord_notifications_status_changes' => ['type' => 'boolean', 'description' => 'Whether to send status change notifications via Discord.'], + 'discord_notifications_database_backups' => ['type' => 'boolean', 'description' => 'Whether to send database backup notifications via Discord.'], + 'discord_notifications_scheduled_tasks' => ['type' => 'boolean', 'description' => 'Whether to send scheduled task notifications via Discord.'], + 'show_boarding' => ['type' => 'boolean', 'description' => 'Whether to show the boarding screen or not.'], + 'resend_enabled' => ['type' => 'boolean', 'description' => 'Whether to enable resending or not.'], + 'resend_api_key' => ['type' => 'string', 'description' => 'The resending API key.'], + 'use_instance_email_settings' => ['type' => 'boolean', 'description' => 'Whether to use instance email settings or not.'], + 'telegram_enabled' => ['type' => 'boolean', 'description' => 'Whether Telegram is enabled or not.'], + 'telegram_token' => ['type' => 'string', 'description' => 'The Telegram token.'], + 'telegram_chat_id' => ['type' => 'string', 'description' => 'The Telegram chat ID.'], + 'telegram_notifications_test' => ['type' => 'boolean', 'description' => 'Whether to send test notifications via Telegram.'], + 'telegram_notifications_deployments' => ['type' => 'boolean', 'description' => 'Whether to send deployment notifications via Telegram.'], + 'telegram_notifications_status_changes' => ['type' => 'boolean', 'description' => 'Whether to send status change notifications via Telegram.'], + 'telegram_notifications_database_backups' => ['type' => 'boolean', 'description' => 'Whether to send database backup notifications via Telegram.'], + 'telegram_notifications_test_message_thread_id' => ['type' => 'string', 'description' => 'The Telegram test message thread ID.'], + 'telegram_notifications_deployments_message_thread_id' => ['type' => 'string', 'description' => 'The Telegram deployment message thread ID.'], + 'telegram_notifications_status_changes_message_thread_id' => ['type' => 'string', 'description' => 'The Telegram status change message thread ID.'], + 'telegram_notifications_database_backups_message_thread_id' => ['type' => 'string', 'description' => 'The Telegram database backup message thread ID.'], + 'custom_server_limit' => ['type' => 'string', 'description' => 'The custom server limit.'], + 'telegram_notifications_scheduled_tasks' => ['type' => 'boolean', 'description' => 'Whether to send scheduled task notifications via Telegram.'], + 'telegram_notifications_scheduled_tasks_thread_id' => ['type' => 'string', 'description' => 'The Telegram scheduled task message thread ID.'], + ] +)] class Team extends Model implements SendsDiscord, SendsEmail { use Notifiable; diff --git a/openapi.yaml b/openapi.yaml index f2a813c19..19e342351 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4,18 +4,135 @@ info: version: '0.1' servers: - - url: 'https://coolify.io/api/v1' + url: 'https://app.coolify.io/api/v1' paths: + /version: + get: + summary: Version + description: 'Get Coolify version.' + operationId: 187b37139844731110757711ee71c215 + responses: + '200': + description: 'Returns the version of the application' + content: + application/json: + schema: + type: string + example: v4.0.0 + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] + /enable: + get: + summary: 'Enable API' + description: 'Enable API (only with root permissions).' + operationId: 595019bae03d08277def667609779ff3 + responses: + '200': + description: 'Enable API.' + content: + application/json: + schema: + properties: + message: { type: string, example: 'API enabled.' } + type: object + '403': + description: 'You are not allowed to enable the API.' + content: + application/json: + schema: + properties: + message: { type: string, example: 'You are not allowed to enable the API.' } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] + /disable: + get: + summary: 'Disable API' + description: 'Disable API (only with root permissions).' + operationId: 50e2486a2d196a996b24a284a283bcdb + responses: + '200': + description: 'Disable API.' + content: + application/json: + schema: + properties: + message: { type: string, example: 'API disabled.' } + type: object + '403': + description: 'You are not allowed to disable the API.' + content: + application/json: + schema: + properties: + message: { type: string, example: 'You are not allowed to disable the API.' } + type: object + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] + /healthcheck: + get: + summary: Healthcheck + description: 'Healthcheck endpoint.' + operationId: 64db893135e686704bb88c3c238022c1 + responses: + '200': + description: 'Healthcheck endpoint.' + content: + application/json: + schema: + type: string + example: OK + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] /teams: get: + tags: + - Teams + summary: List + description: 'Get all teams.' operationId: f9c530b5b25df9601cb87d6a58646f0a responses: '200': - description: 'List of teams' + description: 'List of teams.' + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Team' '401': - description: Unauthorized + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + security: + - + bearerAuth: [] '/teams/{id}': get: + tags: + - Teams + summary: Get + description: 'Get team by TeamId.' operationId: ac57ff546c002032cef44602c46a4e76 parameters: - @@ -26,30 +143,201 @@ paths: schema: type: integer responses: - '401': - description: Unauthorized - content: - application/json: - schema: - properties: - message: { type: string, example: Unauthenticated. } - type: object - '404': - description: 'Team not found' '200': - description: 'Team model' + description: 'List of teams.' content: application/json: schema: - properties: - id: { type: integer, example: 1 } - name: { type: string, example: 'Team 1' } - created_at: { type: string, format: date-time, example: '2021-10-10T10:00:00Z' } - updated_at: { type: string, format: date-time, example: '2021-10-10T10:00:00Z' } - type: object + $ref: '#/components/schemas/Team' + '401': + $ref: '#/components/responses/401' + '400': + $ref: '#/components/responses/400' + '404': + $ref: '#/components/responses/404' + security: + - + bearerAuth: [] components: + schemas: + Team: + description: 'Team model' + properties: + id: + type: integer + description: 'The unique identifier of the team.' + name: + type: string + description: 'The name of the team.' + description: + type: string + description: 'The description of the team.' + personal_team: + type: boolean + description: 'Whether the team is personal or not.' + created_at: + type: string + description: 'The date and time the team was created.' + updated_at: + type: string + description: 'The date and time the team was last updated.' + smtp_enabled: + type: boolean + description: 'Whether SMTP is enabled or not.' + smtp_from_address: + type: string + description: 'The email address to send emails from.' + smtp_from_name: + type: string + description: 'The name to send emails from.' + smtp_recipients: + type: string + description: 'The email addresses to send emails to.' + smtp_host: + type: string + description: 'The SMTP host.' + smtp_port: + type: string + description: 'The SMTP port.' + smtp_encryption: + type: string + description: 'The SMTP encryption.' + smtp_username: + type: string + description: 'The SMTP username.' + smtp_password: + type: string + description: 'The SMTP password.' + smtp_timeout: + type: string + description: 'The SMTP timeout.' + smtp_notifications_test: + type: boolean + description: 'Whether to send test notifications via SMTP.' + smtp_notifications_deployments: + type: boolean + description: 'Whether to send deployment notifications via SMTP.' + smtp_notifications_status_changes: + type: boolean + description: 'Whether to send status change notifications via SMTP.' + smtp_notifications_scheduled_tasks: + type: boolean + description: 'Whether to send scheduled task notifications via SMTP.' + smtp_notifications_database_backups: + type: boolean + description: 'Whether to send database backup notifications via SMTP.' + discord_enabled: + type: boolean + description: 'Whether Discord is enabled or not.' + discord_webhook_url: + type: string + description: 'The Discord webhook URL.' + discord_notifications_test: + type: boolean + description: 'Whether to send test notifications via Discord.' + discord_notifications_deployments: + type: boolean + description: 'Whether to send deployment notifications via Discord.' + discord_notifications_status_changes: + type: boolean + description: 'Whether to send status change notifications via Discord.' + discord_notifications_database_backups: + type: boolean + description: 'Whether to send database backup notifications via Discord.' + discord_notifications_scheduled_tasks: + type: boolean + description: 'Whether to send scheduled task notifications via Discord.' + show_boarding: + type: boolean + description: 'Whether to show the boarding screen or not.' + resend_enabled: + type: boolean + description: 'Whether to enable resending or not.' + resend_api_key: + type: string + description: 'The resending API key.' + use_instance_email_settings: + type: boolean + description: 'Whether to use instance email settings or not.' + telegram_enabled: + type: boolean + description: 'Whether Telegram is enabled or not.' + telegram_token: + type: string + description: 'The Telegram token.' + telegram_chat_id: + type: string + description: 'The Telegram chat ID.' + telegram_notifications_test: + type: boolean + description: 'Whether to send test notifications via Telegram.' + telegram_notifications_deployments: + type: boolean + description: 'Whether to send deployment notifications via Telegram.' + telegram_notifications_status_changes: + type: boolean + description: 'Whether to send status change notifications via Telegram.' + telegram_notifications_database_backups: + type: boolean + description: 'Whether to send database backup notifications via Telegram.' + telegram_notifications_test_message_thread_id: + type: string + description: 'The Telegram test message thread ID.' + telegram_notifications_deployments_message_thread_id: + type: string + description: 'The Telegram deployment message thread ID.' + telegram_notifications_status_changes_message_thread_id: + type: string + description: 'The Telegram status change message thread ID.' + telegram_notifications_database_backups_message_thread_id: + type: string + description: 'The Telegram database backup message thread ID.' + custom_server_limit: + type: string + description: 'The custom server limit.' + telegram_notifications_scheduled_tasks: + type: boolean + description: 'Whether to send scheduled task notifications via Telegram.' + telegram_notifications_scheduled_tasks_thread_id: + type: string + description: 'The Telegram scheduled task message thread ID.' + type: object + responses: + '401': + description: Unauthenticated. + content: + application/json: + schema: + properties: + message: + type: string + example: Unauthenticated. + type: object + '400': + description: 'Invalid token.' + content: + application/json: + schema: + properties: + message: + type: string + example: 'Invalid token.' + type: object + '404': + description: 'Resource not found.' + content: + application/json: + schema: + properties: + message: + type: string + type: object securitySchemes: bearerAuth: type: http - bearerFormat: JWT + description: 'Go to `Keys & Tokens` / `API tokens` and create a new token. Use the token as the bearer token.' scheme: bearer +tags: + - + name: Teams + description: Teams diff --git a/routes/api.php b/routes/api.php index d1500c3e9..5daf6cd01 100644 --- a/routes/api.php +++ b/routes/api.php @@ -3,7 +3,7 @@ use App\Http\Controllers\Api\ApplicationsController; use App\Http\Controllers\Api\DatabasesController; use App\Http\Controllers\Api\DeployController; -use App\Http\Controllers\Api\EnvironmentVariablesController; +use App\Http\Controllers\Api\OtherController; use App\Http\Controllers\Api\ProjectController; use App\Http\Controllers\Api\ResourcesController; use App\Http\Controllers\Api\SecurityController; @@ -13,65 +13,23 @@ use App\Http\Middleware\ApiAllowed; use App\Http\Middleware\IgnoreReadOnlyApiToken; use App\Http\Middleware\OnlyRootApiToken; -use App\Models\InstanceSettings; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; -Route::get('/health', function () { - return 'OK'; -}); -Route::post('/feedback', function (Request $request) { - $content = $request->input('content'); - $webhook_url = config('coolify.feedback_discord_webhook'); - if ($webhook_url) { - Http::post($webhook_url, [ - 'content' => $content, - ]); - } - - return response()->json(['success' => true, 'message' => 'Feedback sent.'], 200); -}); +Route::get('/health', [OtherController::class, 'healthcheck']); +Route::post('/feedback', [OtherController::class, 'feedback']); Route::group([ 'middleware' => ['auth:sanctum', OnlyRootApiToken::class], 'prefix' => 'v1', ], function () { - Route::get('/enable', function () { - $teamId = getTeamIdFromToken(); - if (is_null($teamId)) { - return invalidTokenResponse(); - } - if ($teamId !== '0') { - return response()->json(['message' => 'You are not allowed to enable the API.'], 403); - } - $settings = InstanceSettings::get(); - $settings->update(['is_api_enabled' => true]); - - return response()->json(['success' => true, 'message' => 'API enabled.'], 200); - }); - Route::get('/disable', function () { - $teamId = getTeamIdFromToken(); - if (is_null($teamId)) { - return invalidTokenResponse(); - } - if ($teamId !== '0') { - return response()->json(['message' => 'You are not allowed to disable the API.'], 403); - } - $settings = InstanceSettings::get(); - $settings->update(['is_api_enabled' => false]); - - return response()->json(['success' => true, 'message' => 'API disabled.'], 200); - }); - + Route::get('/enable', [OtherController::class, 'enable_api']); + Route::get('/disable', [OtherController::class, 'disable_api']); }); Route::group([ 'middleware' => ['auth:sanctum', ApiAllowed::class], 'prefix' => 'v1', ], function () { - Route::get('/version', function () { - return response(config('version')); - }); + Route::get('/version', [OtherController::class, 'version']); Route::get('/teams', [TeamController::class, 'teams']); Route::get('/teams/current', [TeamController::class, 'current_team']);