From 2c60c6540ae27540d13eb96826bcdd826f7874a4 Mon Sep 17 00:00:00 2001 From: Oleksander Piskun Date: Tue, 23 Jun 2026 13:11:35 +0000 Subject: [PATCH] feat(openapi): add OpenAPI specification generation Signed-off-by: Oleksander Piskun --- .github/workflows/command-openapi.yml | 199 + .github/workflows/openapi.yml | 96 + REUSE.toml | 6 + appinfo/routes.php | 9 +- composer.json | 1 + lib/Capabilities.php | 3 + lib/Controller/AppConfigController.php | 44 +- lib/Controller/ConfigController.php | 12 + lib/Controller/DaemonConfigController.php | 124 +- lib/Controller/ExAppProxyController.php | 4 +- lib/Controller/ExAppsPageController.php | 98 +- lib/Controller/HarpController.php | 4 +- lib/Controller/NotificationsController.php | 17 +- lib/Controller/OCSApiController.php | 65 +- lib/Controller/OCSExAppController.php | 74 +- lib/Controller/OCSSettingsController.php | 36 +- lib/Controller/OCSUiController.php | 231 +- lib/Controller/OccCommandController.php | 48 +- lib/Controller/PreferencesController.php | 44 +- lib/Controller/TalkBotController.php | 47 +- lib/Controller/TaskProcessingController.php | 43 +- lib/Controller/TopMenuController.php | 2 + lib/Db/Console/ExAppOccCommand.php | 5 + lib/Db/DaemonConfig.php | 7 +- lib/Db/ExApp.php | 4 +- lib/Db/ExAppConfig.php | 5 + lib/Db/ExAppPreference.php | 5 + .../TaskProcessing/TaskProcessingProvider.php | 5 + lib/Db/UI/FilesActionsMenu.php | 5 + lib/Db/UI/InitialState.php | 5 + lib/Db/UI/Script.php | 5 + lib/Db/UI/Style.php | 5 + lib/Db/UI/TopMenu.php | 5 + lib/PublicCapabilities.php | 3 + lib/ResponseDefinitions.php | 185 + openapi-administration.json | 3953 +++++++ openapi-full.json | 9131 +++++++++++++++++ openapi.json | 5282 ++++++++++ .../Controller/AppConfigControllerTest.php | 14 +- .../Controller/OCSSettingsControllerTest.php | 2 +- tests/php/Controller/OCSUiControllerTest.php | 2 +- .../Controller/OccCommandControllerTest.php | 16 +- .../Controller/PreferencesControllerTest.php | 12 +- .../php/Controller/TalkBotControllerTest.php | 2 +- .../TaskProcessingControllerTest.php | 8 +- vendor-bin/openapi-extractor/composer.json | 10 + vendor-bin/openapi-extractor/composer.lock | 247 + 47 files changed, 19996 insertions(+), 134 deletions(-) create mode 100644 .github/workflows/command-openapi.yml create mode 100644 .github/workflows/openapi.yml create mode 100644 lib/ResponseDefinitions.php create mode 100644 openapi-administration.json create mode 100644 openapi-full.json create mode 100644 openapi.json create mode 100644 vendor-bin/openapi-extractor/composer.json create mode 100644 vendor-bin/openapi-extractor/composer.lock diff --git a/.github/workflows/command-openapi.yml b/.github/workflows/command-openapi.yml new file mode 100644 index 000000000..9660fd61a --- /dev/null +++ b/.github/workflows/command-openapi.yml @@ -0,0 +1,199 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization +# +# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: MIT + +name: OpenAPI Command +on: + issue_comment: + types: [created] + +permissions: + contents: read + +jobs: + init: + runs-on: ubuntu-latest + + # On pull requests and if the comment starts with `/openapi` + if: github.event.issue.pull_request != '' && startsWith(github.event.comment.body, '/openapi') + + outputs: + git_path: ${{ steps.git-path.outputs.path }} + arg1: ${{ steps.command.outputs.arg1 }} + arg2: ${{ steps.command.outputs.arg2 }} + head_ref: ${{ steps.comment-branch.outputs.head_ref }} + base_ref: ${{ steps.comment-branch.outputs.base_ref }} + + steps: + - name: Get repository from pull request comment + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + id: get-repository + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const pull = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }); + + const repositoryName = pull.data.head?.repo?.full_name + console.log(repositoryName) + return repositoryName + + - name: Disabled on forks + if: ${{ fromJSON(steps.get-repository.outputs.result) != github.repository }} + run: | + echo 'Can not execute /openapi on forks' + exit 1 + + - name: Check actor permission + uses: skjnldsv/check-actor-permission@69e92a3c4711150929bca9fcf34448c5bf5526e7 # v3.0 + with: + require: write + + - name: Add reaction on start + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reactions: '+1' + + - name: Parse command + uses: skjnldsv/parse-command-comment@5c955203c52424151e6d0e58fb9de8a9f6a605a1 # v3.1 + id: command + + # Init path depending on which command is run + - name: Init path + id: git-path + run: | + if ${{ startsWith(steps.command.outputs.arg1, '/') }}; then + echo "path=${{steps.command.outputs.arg1}}" >> $GITHUB_OUTPUT + else + echo "path=${{steps.command.outputs.arg2}}" >> $GITHUB_OUTPUT + fi + + - name: Init branch + uses: xt0rted/pull-request-comment-branch@e8b8daa837e8ea7331c0003c9c316a64c6d8b0b1 # v3.0.0 + id: comment-branch + + - name: Add reaction on failure + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 + if: failure() + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reactions: '-1' + + process: + runs-on: ubuntu-latest + needs: init + + steps: + - name: Restore cached git repository + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: .git + key: git-repo + + - name: Checkout ${{ needs.init.outputs.head_ref }} + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + # Needed to allow force push later + persist-credentials: true + token: ${{ secrets.COMMAND_BOT_PAT }} + fetch-depth: 0 + ref: ${{ needs.init.outputs.head_ref }} + + - name: Setup git + run: | + git config --local user.email 'nextcloud-command@users.noreply.github.com' + git config --local user.name 'nextcloud-command' + + - name: Check Typescript OpenApi types + id: check_typescript_openapi + uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0 + with: + files: "src/types/openapi/openapi*.ts" + + - name: Read package.json node and npm engines version + if: steps.check_typescript_openapi.outputs.files_exists == 'true' + uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 + id: node_versions + # Continue if no package.json + continue-on-error: true + with: + fallbackNode: '^24' + fallbackNpm: '^11.3' + + - name: Set up node ${{ steps.node_versions.outputs.nodeVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ steps.node_versions.outputs.nodeVersion }} + + - name: Set up npm ${{ steps.node_versions.outputs.npmVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + run: npm i -g 'npm@${{ steps.node_versions.outputs.npmVersion }}' + + - name: Rebase to ${{ needs.init.outputs.base_ref }} + if: ${{ contains(needs.init.outputs.arg1, 'rebase') }} + run: | + git fetch origin '${{ needs.init.outputs.base_ref }}:${{ needs.init.outputs.base_ref }}' + git rebase 'origin/${{ needs.init.outputs.base_ref }}' + + - name: Install dependencies + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: | + npm ci + + - name: Set up dependencies + run: composer i + + - name: Regenerate OpenAPI + run: composer run openapi + + - name: Commit default + if: ${{ !contains(needs.init.outputs.arg1, 'fixup') && !contains(needs.init.outputs.arg1, 'amend') }} + run: | + git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}' + git commit --signoff -m 'fix(openapi): Regenerate OpenAPI assets' + + - name: Commit fixup + if: ${{ contains(needs.init.outputs.arg1, 'fixup') }} + run: | + git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}' + git commit --fixup=HEAD --signoff + + - name: Commit amend + if: ${{ contains(needs.init.outputs.arg1, 'amend') }} + run: | + git add '${{ github.workspace }}${{ needs.init.outputs.git_path }}' + git commit --amend --no-edit --signoff + # Remove any [skip ci] from the amended commit + git commit --amend -m "$(git log -1 --format='%B' | sed '/\[skip ci\]/d')" + + - name: Push normally + if: ${{ !contains(needs.init.outputs.arg1, 'rebase') && !contains(needs.init.outputs.arg1, 'amend') }} + run: git push origin '${{ needs.init.outputs.head_ref }}' + + - name: Force push + if: ${{ contains(needs.init.outputs.arg1, 'rebase') || contains(needs.init.outputs.arg1, 'amend') }} + run: git push --force-with-lease origin '${{ needs.init.outputs.head_ref }}' + + - name: Add reaction on failure + uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0 + if: failure() + with: + token: ${{ secrets.COMMAND_BOT_PAT }} + repository: ${{ github.event.repository.full_name }} + comment-id: ${{ github.event.comment.id }} + reactions: '-1' diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml new file mode 100644 index 000000000..925dd8dbb --- /dev/null +++ b/.github/workflows/openapi.yml @@ -0,0 +1,96 @@ +# This workflow is provided via the organization template repository +# +# https://github.com/nextcloud/.github +# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization +# +# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-FileCopyrightText: 2024 Arthur Schiwon +# SPDX-License-Identifier: MIT + +name: OpenAPI + +on: pull_request + +permissions: + contents: read + +concurrency: + group: openapi-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + openapi: + runs-on: ubuntu-latest + + if: ${{ github.repository_owner != 'nextcloud-gmbh' }} + + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Get php version + id: php_versions + uses: icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2 + + - name: Set up php + uses: shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc # 2.37.1 + with: + php-version: ${{ steps.php_versions.outputs.php-available }} + extensions: xml + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check Typescript OpenApi types + id: check_typescript_openapi + uses: andstor/file-existence-action@558493d6c74bf472d87c84eab196434afc2fa029 # v3.1.0 + with: + files: "src/types/openapi/openapi*.ts" + + - name: Read package.json node and npm engines version + if: steps.check_typescript_openapi.outputs.files_exists == 'true' + uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3 + id: node_versions + # Continue if no package.json + continue-on-error: true + with: + fallbackNode: '^24' + fallbackNpm: '^11.3' + + - name: Set up node ${{ steps.node_versions.outputs.nodeVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ steps.node_versions.outputs.nodeVersion }} + + - name: Set up npm ${{ steps.node_versions.outputs.npmVersion }} + if: ${{ steps.node_versions.outputs.nodeVersion }} + run: npm i -g 'npm@${{ steps.node_versions.outputs.npmVersion }}' + + - name: Install dependencies + if: ${{ steps.node_versions.outputs.nodeVersion }} + env: + CYPRESS_INSTALL_BINARY: 0 + PUPPETEER_SKIP_DOWNLOAD: true + run: | + npm ci + + - name: Set up dependencies + run: composer i + + - name: Regenerate OpenAPI + run: composer run openapi + + - name: Check openapi*.json and typescript changes + run: | + bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please run \"composer run openapi\" and commit the openapi*.json files and (if applicable) src/types/openapi/openapi*.ts, see the section \"Show changes on failure\" for details' && exit 1)" + + - name: Show changes on failure + if: failure() + run: | + git status + git --no-pager diff + exit 1 # make it red to grab attention diff --git a/REUSE.toml b/REUSE.toml index 8cff69dd8..c0815dd39 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -17,6 +17,12 @@ precedence = "aggregate" SPDX-FileCopyrightText = "2023 Nextcloud GmbH and Nextcloud contributors" SPDX-License-Identifier = "AGPL-3.0-or-later" +[[annotations]] +path = ["openapi.json", "openapi-**.json"] +precedence = "aggregate" +SPDX-FileCopyrightText = "2024 Nextcloud GmbH and Nextcloud contributors" +SPDX-License-Identifier = "AGPL-3.0-or-later" + # Workaround annotating the folders [[annotations]] path = ["docs/**", "js/**", ""] diff --git a/appinfo/routes.php b/appinfo/routes.php index 0b208af9f..abe7b5503 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -34,7 +34,7 @@ // ExApps actions ['name' => 'ExAppsPage#listCategories', 'url' => '/apps/categories', 'verb' => 'GET' , 'root' => ''], ['name' => 'ExAppsPage#listApps', 'url' => '/apps/list', 'verb' => 'GET' , 'root' => ''], - ['name' => 'ExAppsPage#enableApp', 'url' => '/apps/enable/{appId}/{daemonId}', 'verb' => 'GET' , 'root' => ''], + ['name' => 'ExAppsPage#enableApp', 'url' => '/apps/enable/{appId}/{daemonId}', 'verb' => 'GET' , 'root' => '', 'postfix' => 'get'], ['name' => 'ExAppsPage#enableApp', 'url' => '/apps/enable/{appId}/{daemonId}', 'verb' => 'POST' , 'root' => ''], ['name' => 'ExAppsPage#getAppStatus', 'url' => '/apps/status/{appId}', 'verb' => 'GET' , 'root' => ''], ['name' => 'ExAppsPage#getAppLogs', 'url' => '/apps/logs/{appId}', 'verb' => 'GET' , 'root' => ''], @@ -42,8 +42,6 @@ ['name' => 'ExAppsPage#disableApp', 'url' => '/apps/disable/{appId}', 'verb' => 'GET' , 'root' => ''], ['name' => 'ExAppsPage#updateApp', 'url' => '/apps/update/{appId}', 'verb' => 'GET' , 'root' => ''], ['name' => 'ExAppsPage#uninstallApp', 'url' => '/apps/uninstall/{appId}', 'verb' => 'GET' , 'root' => ''], - ['name' => 'ExAppsPage#viewApps', 'url' => '/apps/{category}', 'verb' => 'GET', 'defaults' => ['category' => ''] , 'root' => ''], - ['name' => 'ExAppsPage#viewApps', 'url' => '/apps/{category}/{id}', 'verb' => 'GET', 'defaults' => ['category' => '', 'id' => ''] , 'root' => ''], ['name' => 'ExAppsPage#force', 'url' => '/apps/force', 'verb' => 'POST' , 'root' => ''], // DaemonConfig actions @@ -104,11 +102,6 @@ // Notifications ['name' => 'Notifications#sendNotification', 'url' => '/api/v1/notification', 'verb' => 'POST'], - // Events - ['name' => 'EventsListener#registerListener', 'url' => '/api/v1/events_listener', 'verb' => 'POST'], - ['name' => 'EventsListener#unregisterListener', 'url' => '/api/v1/events_listener', 'verb' => 'DELETE'], - ['name' => 'EventsListener#getListener', 'url' => '/api/v1/events_listener', 'verb' => 'GET'], - // Commands ['name' => 'OccCommand#registerCommand', 'url' => '/api/v1/occ_command', 'verb' => 'POST'], ['name' => 'OccCommand#unregisterCommand', 'url' => '/api/v1/occ_command', 'verb' => 'DELETE'], diff --git a/composer.json b/composer.json index d6bcc8118..22a632742 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './vendor-bin/*' -print0 | xargs -0 -n1 php -l", "cs:check": "php-cs-fixer fix ./lib --dry-run --diff", "cs:fix": "php-cs-fixer fix ./lib", + "openapi": "generate-spec --verbose", "psalm": "psalm.phar --threads=1", "psalm:update-baseline": "psalm.phar --threads=1 --update-baseline", "psalm:update-baseline:force": "psalm.phar --threads=1 --update-baseline --set-baseline=tests/psalm-baseline.xml", diff --git a/lib/Capabilities.php b/lib/Capabilities.php index 8510d83f6..c74f86f9f 100644 --- a/lib/Capabilities.php +++ b/lib/Capabilities.php @@ -22,6 +22,9 @@ public function __construct( ) { } + /** + * @return array{app_api: array{loglevel: int, version: string}} + */ public function getCapabilities(): array { $capabilities = [ 'loglevel' => intval($this->config->getSystemValue('loglevel', 2)), diff --git a/lib/Controller/AppConfigController.php b/lib/Controller/AppConfigController.php index c1cfe12d0..d93e0502c 100644 --- a/lib/Controller/AppConfigController.php +++ b/lib/Controller/AppConfigController.php @@ -12,6 +12,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; use OCA\AppAPI\Db\ExAppConfig; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\ExAppConfigService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; @@ -22,6 +23,10 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; +/** + * @psalm-import-type AppAPIExAppConfig from ResponseDefinitions + * @psalm-import-type AppAPIExAppConfigValue from ResponseDefinitions + */ class AppConfigController extends OCSController { protected $request; @@ -35,7 +40,16 @@ public function __construct( } /** - * @throws OCSBadRequestException + * Set a configuration value for the calling ExApp + * + * @param string $configKey Configuration key + * @param mixed $configValue Configuration value + * @param ?int $sensitive Whether the value is sensitive and should be stored encrypted (1) or not (0) + * + * @return DataResponse + * @throws OCSBadRequestException Config key is empty or the value could not be set + * + * 200: Config value set */ #[AppAPIAuth] #[PublicPage] @@ -44,32 +58,48 @@ public function setAppConfigValue(string $configKey, mixed $configValue, ?int $s if ($configKey === '') { throw new OCSBadRequestException('Config key cannot be empty'); } - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppConfigService->setAppConfigValue($appId, $configKey, $configValue, $sensitive); if ($result instanceof ExAppConfig) { - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } throw new OCSBadRequestException('Error setting app config value'); } + /** + * Get configuration values of the calling ExApp + * + * @param list $configKeys Configuration keys to retrieve + * + * @return DataResponse, array{}> + * + * 200: Config values returned + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getAppConfigValues(array $configKeys): DataResponse { - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppConfigService->getAppConfigValues($appId, $configKeys); return new DataResponse($result, Http::STATUS_OK); } /** - * @throws OCSBadRequestException - * @throws OCSNotFoundException + * Delete configuration values of the calling ExApp + * + * @param list $configKeys Configuration keys to delete + * + * @return DataResponse + * @throws OCSBadRequestException Failed to delete the config values + * @throws OCSNotFoundException No matching config values were found + * + * 200: Number of deleted config values returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function deleteAppConfigValues(array $configKeys): DataResponse { - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppConfigService->deleteAppConfigValues($configKeys, $appId); if ($result === -1) { throw new OCSBadRequestException('Error deleting app config values'); diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index fa447ff38..374613391 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -11,11 +11,14 @@ use OCA\AppAPI\AppInfo\Application; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\DataResponse; use OCP\IAppConfig; use OCP\IRequest; +#[OpenAPI(OpenAPI::SCOPE_ADMINISTRATION)] class ConfigController extends Controller { public function __construct( @@ -26,6 +29,15 @@ public function __construct( parent::__construct($appName, $request); } + /** + * Update the AppAPI admin configuration + * + * @param array $values Configuration key-value pairs to store + * + * @return DataResponse + * + * 200: Configuration updated + */ #[NoCSRFRequired] public function setAdminConfig(array $values): DataResponse { foreach ($values as $key => $value) { diff --git a/lib/Controller/DaemonConfigController.php b/lib/Controller/DaemonConfigController.php index cb738f6de..e85bd3223 100644 --- a/lib/Controller/DaemonConfigController.php +++ b/lib/Controller/DaemonConfigController.php @@ -12,11 +12,13 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Db\DaemonConfig; use OCA\AppAPI\DeployActions\DockerActions; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\AppAPIService; use OCA\AppAPI\Service\DaemonConfigService; use OCA\AppAPI\Service\ExAppService; use OCP\AppFramework\ApiController; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; @@ -27,7 +29,11 @@ /** * DaemonConfig actions (for UI) + * + * @psalm-import-type AppAPIDaemonConfig from ResponseDefinitions + * @psalm-import-type AppAPIDaemonConfigWithAppsCount from ResponseDefinitions */ +#[OpenAPI(OpenAPI::SCOPE_ADMINISTRATION)] class DaemonConfigController extends ApiController { public function __construct( @@ -43,6 +49,13 @@ public function __construct( parent::__construct(Application::APP_ID, $request); } + /** + * Get all registered deploy daemons together with the number of ExApps each one runs + * + * @return JSONResponse, default_daemon_config: string}, array{}> + * + * 200: Daemons returned + */ public function getAllDaemonConfigs(): Response { return new JSONResponse([ 'daemons' => $this->daemonConfigService->getDaemonConfigsWithAppsCount(), @@ -50,6 +63,16 @@ public function getAllDaemonConfigs(): Response { ]); } + /** + * Register a new deploy daemon + * + * @param array $daemonConfigParams Daemon configuration parameters + * @param bool $defaultDaemon Whether to set the new daemon as the default one + * + * @return JSONResponse + * + * 200: Daemon registered + */ #[PasswordConfirmationRequired] public function registerDaemonConfig(array $daemonConfigParams, bool $defaultDaemon = false): Response { $daemonConfig = $this->daemonConfigService->registerDaemonConfig($daemonConfigParams); @@ -58,10 +81,20 @@ public function registerDaemonConfig(array $daemonConfigParams, bool $defaultDae } return new JSONResponse([ 'success' => $daemonConfig !== null, - 'daemonConfig' => $daemonConfig, + 'daemonConfig' => $daemonConfig?->jsonSerialize(), ]); } + /** + * Update a registered deploy daemon + * + * @param string $name Name of the daemon to update + * @param array $daemonConfigParams New daemon configuration parameters + * + * @return JSONResponse + * + * 200: Daemon updated + */ #[PasswordConfirmationRequired] public function updateDaemonConfig(string $name, array $daemonConfigParams): Response { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); @@ -99,10 +132,19 @@ public function updateDaemonConfig(string $name, array $daemonConfigParams): Res return new JSONResponse([ 'success' => true, - 'daemonConfig' => $updatedDaemonConfig, + 'daemonConfig' => $updatedDaemonConfig->jsonSerialize(), ]); } + /** + * Unregister a deploy daemon and remove the ExApps that run on it + * + * @param string $name Name of the daemon to remove + * + * @return JSONResponse + * + * 200: Daemon unregistered + */ #[PasswordConfirmationRequired] public function unregisterDaemonConfig(string $name): Response { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); @@ -114,10 +156,19 @@ public function unregisterDaemonConfig(string $name): Response { $daemonConfig = $this->daemonConfigService->unregisterDaemonConfig($daemonConfig); return new JSONResponse([ 'success' => $daemonConfig !== null, - 'daemonConfig' => $daemonConfig, + 'daemonConfig' => $daemonConfig?->jsonSerialize(), ]); } + /** + * Verify the connection to a registered deploy daemon + * + * @param string $name Name of the daemon to check + * + * @return JSONResponse + * + * 200: Connection check result returned + */ public function verifyDaemonConnection(string $name): Response { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); $this->dockerActions->initGuzzleClient($daemonConfig); @@ -127,6 +178,15 @@ public function verifyDaemonConnection(string $name): Response { ]); } + /** + * Check the connection to a deploy daemon from the given parameters + * + * @param array $daemonParams Daemon parameters to check + * + * @return JSONResponse + * + * 200: Connection check result returned + */ public function checkDaemonConnection(array $daemonParams): Response { // Safely check if "haproxy_password" exists before accessing it // note: UI passes here 'deploy_config' instead of 'deployConfig' @@ -166,6 +226,17 @@ public function checkDaemonConnection(array $daemonParams): Response { ]); } + /** + * Start a test deployment on a deploy daemon + * + * @param string $name Name of the daemon to deploy on + * + * @return JSONResponse}, array{}>|JSONResponse|JSONResponse + * + * 200: Test deploy started + * 404: Daemon config not found + * 500: Test deploy could not be started + */ public function startTestDeploy(string $name): Response { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); if (!$daemonConfig) { @@ -201,6 +272,15 @@ public function startTestDeploy(string $name): Response { ]); } + /** + * Stop the running test deployment + * + * @param string $name Name of the daemon the test runs on + * + * @return JSONResponse + * + * 200: Test deploy stopped + */ public function stopTestDeploy(string $name): Response { $exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID); if ($exApp !== null) { @@ -223,6 +303,16 @@ public function stopTestDeploy(string $name): Response { ]); } + /** + * Get the status of the running test deployment + * + * @param string $name Name of the daemon the test runs on + * + * @return JSONResponse, array{}>|JSONResponse + * + * 200: Test deploy status returned + * 404: Test ExApp not found + */ public function getTestDeployStatus(string $name): Response { $exApp = $this->exAppService->getExApp(Application::TEST_DEPLOY_APPID); if (is_null($exApp) || $exApp->getDaemonConfigName() !== $name) { @@ -231,6 +321,18 @@ public function getTestDeployStatus(string $name): Response { return new JSONResponse($exApp->getStatus()); } + /** + * Add a Docker registry mapping to a deploy daemon + * + * @param string $name Name of the daemon + * @param array $registryMap Docker registry mapping to add + * + * @return JSONResponse|JSONResponse|JSONResponse + * + * 200: Registry added + * 404: Daemon config not found + * 500: Registry could not be added + */ #[PasswordConfirmationRequired] public function addDaemonDockerRegistry(string $name, array $registryMap): JSONResponse { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); @@ -241,9 +343,21 @@ public function addDaemonDockerRegistry(string $name, array $registryMap): JSONR if ($daemonConfig === null) { return new JSONResponse(['error' => $this->l10n->t('Error adding Docker registry')], Http::STATUS_INTERNAL_SERVER_ERROR); } - return new JSONResponse($daemonConfig, Http::STATUS_OK); + return new JSONResponse($daemonConfig->jsonSerialize(), Http::STATUS_OK); } + /** + * Remove a Docker registry mapping from a deploy daemon + * + * @param string $name Name of the daemon + * @param array $registryMap Docker registry mapping to remove + * + * @return JSONResponse|JSONResponse|JSONResponse + * + * 200: Registry removed + * 404: Daemon config not found + * 500: Registry could not be removed + */ #[PasswordConfirmationRequired] public function removeDaemonDockerRegistry(string $name, array $registryMap): JSONResponse { $daemonConfig = $this->daemonConfigService->getDaemonConfigByName($name); @@ -254,6 +368,6 @@ public function removeDaemonDockerRegistry(string $name, array $registryMap): JS if ($daemonConfig === null) { return new JSONResponse(['error' => $this->l10n->t('Error removing Docker registry')], Http::STATUS_INTERNAL_SERVER_ERROR); } - return new JSONResponse($daemonConfig, Http::STATUS_OK); + return new JSONResponse($daemonConfig->jsonSerialize(), Http::STATUS_OK); } } diff --git a/lib/Controller/ExAppProxyController.php b/lib/Controller/ExAppProxyController.php index 557ed305f..be13b3330 100644 --- a/lib/Controller/ExAppProxyController.php +++ b/lib/Controller/ExAppProxyController.php @@ -23,6 +23,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\Response; @@ -33,6 +34,7 @@ use OCP\Security\Bruteforce\IThrottler; use Psr\Log\LoggerInterface; +#[OpenAPI(OpenAPI::SCOPE_IGNORE)] class ExAppProxyController extends Controller { public function __construct( @@ -141,7 +143,7 @@ public function ExAppPost(string $appId, string $other): Response { RequestOptions::HEADERS => $this->buildHeadersWithExclude($route, getallheaders()), RequestOptions::TIMEOUT => 0, ]; - if (str_starts_with($this->request->getHeader('Content-Type'), 'multipart/form-data') || count($_FILES) > 0) { + if (str_starts_with($this->request->getHeader('content-type'), 'multipart/form-data') || count($_FILES) > 0) { unset($options['headers']['Content-Type']); unset($options['headers']['Content-Length']); $options[RequestOptions::MULTIPART] = $this->buildMultipartFormData($_POST, $_FILES); diff --git a/lib/Controller/ExAppsPageController.php b/lib/Controller/ExAppsPageController.php index eb13e34dc..dd6f6c1ed 100644 --- a/lib/Controller/ExAppsPageController.php +++ b/lib/Controller/ExAppsPageController.php @@ -19,6 +19,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\DeployActions\DockerActions; use OCA\AppAPI\Fetcher\ExAppFetcher; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\AppAPIService; use OCA\AppAPI\Service\DaemonConfigService; use OCA\AppAPI\Service\ExAppDeployOptionsService; @@ -27,6 +28,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired; use OCP\AppFramework\Http\DataDownloadResponse; use OCP\AppFramework\Http\JSONResponse; @@ -38,7 +40,11 @@ /** * ExApps actions controller similar to default one with project-specific changes and additions + * + * @psalm-import-type AppAPICategory from ResponseDefinitions + * @psalm-import-type AppAPIDeployOptions from ResponseDefinitions */ +#[OpenAPI(OpenAPI::SCOPE_ADMINISTRATION)] class ExAppsPageController extends Controller { public function __construct( @@ -178,6 +184,13 @@ private function getAppsForCategory(string $requestedCategory = ''): array { return $formattedApps; } + /** + * Get the list of ExApps available in the App Store together with locally installed ones + * + * @return JSONResponse>, status: string}, array{}> + * + * 200: ExApps list returned + */ #[NoCSRFRequired] public function listApps(): JSONResponse { $apps = $this->getAppsForCategory(''); @@ -313,6 +326,18 @@ private function buildLocalAppsList(array $apps, array $exApps): array { return array_merge($apps, $formattedLocalApps); } + /** + * Deploy and enable, or just enable, an ExApp + * + * @param string $appId ID of the ExApp + * @param string $daemonId Name of the deploy daemon to use + * @param array $deployOptions Deploy options (environment variables, mounts) + * + * @return JSONResponse|JSONResponse + * + * 200: ExApp enabled + * 500: ExApp could not be enabled + */ #[PasswordConfirmationRequired] public function enableApp(string $appId, string $daemonId, array $deployOptions = []): JSONResponse { $updateRequired = false; @@ -375,6 +400,16 @@ public function enableApp(string $appId, string $daemonId, array $deployOptions return new JSONResponse(['data' => ['update_required' => $updateRequired]]); } + /** + * Disable an ExApp + * + * @param string $appId ID of the ExApp + * + * @return JSONResponse, array{}>|JSONResponse + * + * 200: ExApp disabled + * 500: ExApp could not be disabled + */ #[PasswordConfirmationRequired] public function disableApp(string $appId): JSONResponse { $exApp = $this->exAppService->getExApp($appId); @@ -389,8 +424,14 @@ public function disableApp(string $appId): JSONResponse { } /** - * Default forced ExApp update process. - * Update approval via password confirmation. + * Update an ExApp + * + * @param string $appId ID of the ExApp + * + * @return JSONResponse, array{}>|JSONResponse + * + * 200: ExApp updated + * 500: ExApp could not be updated */ #[PasswordConfirmationRequired] #[NoCSRFRequired] @@ -429,7 +470,15 @@ public function updateApp(string $appId): JSONResponse { } /** - * Unregister ExApp, remove container by default + * Unregister an ExApp and optionally remove its container and data + * + * @param string $appId ID of the ExApp + * @param bool $removeContainer Whether to remove the ExApp container + * @param bool $removeData Whether to remove the ExApp data volume + * + * @return JSONResponse, array{}> + * + * 200: ExApp uninstalled */ #[PasswordConfirmationRequired] public function uninstallApp(string $appId, bool $removeContainer = true, bool $removeData = false): JSONResponse { @@ -459,7 +508,13 @@ public function uninstallApp(string $appId, bool $removeContainer = true, bool $ } /** - * Using default force mechanism for ExApps + * Mark an ExApp as compatible with the current Nextcloud version + * + * @param string $appId ID of the ExApp + * + * @return JSONResponse, array{}> + * + * 200: Compatibility requirement overwritten */ #[PasswordConfirmationRequired] public function force(string $appId): JSONResponse { @@ -469,14 +524,25 @@ public function force(string $appId): JSONResponse { } /** - * Get all available categories + * Get all available App Store categories + * + * @return JSONResponse, array{}> + * + * 200: Categories returned */ public function listCategories(): JSONResponse { return new JSONResponse($this->getAllCategories()); } /** - * Get ExApp status, that includes initialization information + * Get the status of an ExApp, including its initialization information + * + * @param string $appId ID of the ExApp + * + * @return JSONResponse, array{}>|JSONResponse + * + * 200: ExApp status returned + * 404: ExApp not found */ #[NoCSRFRequired] public function getAppStatus(string $appId): JSONResponse { @@ -487,6 +553,16 @@ public function getAppStatus(string $appId): JSONResponse { return new JSONResponse($exApp->getStatus()); } + /** + * Download the container logs of an ExApp + * + * @param string $appId ID of the ExApp + * @param string $tail Number of lines to return from the end of the logs, or 'all' + * + * @return DataDownloadResponse + * + * 200: ExApp logs returned + */ #[NoCSRFRequired] public function getAppLogs(string $appId, string $tail = 'all'): DataDownloadResponse { $exApp = $this->exAppService->getExApp($appId); @@ -519,6 +595,16 @@ public function getAppLogs(string $appId, string $tail = 'all'): DataDownloadRes } } + /** + * Get the deploy options of an ExApp + * + * @param string $appId ID of the ExApp + * + * @return JSONResponse|JSONResponse + * + * 200: Deploy options returned + * 404: ExApp not found + */ public function getAppDeployOptions(string $appId) { $exApp = $this->exAppService->getExApp($appId); if (is_null($exApp)) { diff --git a/lib/Controller/HarpController.php b/lib/Controller/HarpController.php index be3d2814f..7f4430122 100644 --- a/lib/Controller/HarpController.php +++ b/lib/Controller/HarpController.php @@ -17,6 +17,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\DataResponse; use OCP\IGroupManager; @@ -26,6 +27,7 @@ use OCP\Security\ICrypto; use Psr\Log\LoggerInterface; +#[OpenAPI(OpenAPI::SCOPE_IGNORE)] class HarpController extends Controller { protected $request; @@ -57,7 +59,7 @@ private function validateHarpSharedKey(ExApp $exApp): bool { return false; } - $headerHarpKey = $this->request->getHeader('HARP-SHARED-KEY'); + $headerHarpKey = $this->request->getHeader('harp-shared-key'); if ($headerHarpKey === '' || $headerHarpKey !== $harpKey) { $this->logger->error('Harp shared key is not valid'); $this->throttler->registerAttempt(Application::APP_ID, $this->request->getRemoteAddress(), [ diff --git a/lib/Controller/NotificationsController.php b/lib/Controller/NotificationsController.php index 4656b648c..b130f122f 100644 --- a/lib/Controller/NotificationsController.php +++ b/lib/Controller/NotificationsController.php @@ -12,6 +12,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; use OCA\AppAPI\Notifications\ExNotificationsManager; +use OCA\AppAPI\ResponseDefinitions; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\PublicPage; @@ -21,6 +22,9 @@ use OCP\IRequest; use OCP\Notification\INotification; +/** + * @psalm-import-type AppAPINotification from ResponseDefinitions + */ class NotificationsController extends OCSController { protected $request; @@ -33,12 +37,21 @@ public function __construct( $this->request = $request; } + /** + * Send a notification to a user on behalf of the calling ExApp + * + * @param array $params Notification parameters + * + * @return DataResponse + * + * 200: Notification sent + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function sendNotification(array $params): Response { - $appId = $this->request->getHeader('EX-APP-ID'); - $userId = explode(':', base64_decode($this->request->getHeader('AUTHORIZATION-APP-API')), 2)[0]; + $appId = $this->request->getHeader('ex-app-id'); + $userId = explode(':', base64_decode($this->request->getHeader('authorization-app-api')), 2)[0]; $notification = $this->exNotificationsManager->sendNotification($appId, $userId, $params); return new DataResponse($this->notificationToArray($notification), Http::STATUS_OK); } diff --git a/lib/Controller/OCSApiController.php b/lib/Controller/OCSApiController.php index 70369f784..8659c3dd7 100644 --- a/lib/Controller/OCSApiController.php +++ b/lib/Controller/OCSApiController.php @@ -44,7 +44,15 @@ public function __construct( } /** - * @throws OCSBadRequestException + * Log a message to the Nextcloud log on behalf of an ExApp + * + * @param int $level Log level (0 - debug, 1 - info, 2 - warning, 3 - error, 4 - fatal) + * @param string $message Message to log + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException Invalid log level + * + * 200: Message logged successfully */ #[AppAPIAuth] #[PublicPage] @@ -54,7 +62,7 @@ public function __construct( public function log(int $level, string $message): DataResponse { try { $this->logger->log($level, $message, [ - 'app' => $this->request->getHeader('EX-APP-ID'), + 'app' => $this->request->getHeader('ex-app-id'), ]); return new DataResponse(); } catch (InvalidArgumentException) { @@ -63,6 +71,13 @@ public function log(int $level, string $message): DataResponse { } } + /** + * Get a list of all Nextcloud user IDs + * + * @return DataResponse, array{}> + * + * 200: Users list returned + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] @@ -70,6 +85,20 @@ public function getNCUsersList(): DataResponse { return new DataResponse($this->exAppService->getNCUsersList(), Http::STATUS_OK); } + /** + * Update the initialization progress of an ExApp by its appid + * + * @param string $appId ID of the ExApp + * @param int $progress Initialization progress in percent (0-100) + * @param string $error Error message in case the initialization failed + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Initialization progress updated + * 404: ExApp not found + * + * @deprecated use setAppInitProgress (PUT /ex-app/status) instead + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] @@ -83,12 +112,23 @@ public function setAppInitProgressDeprecated(string $appId, int $progress, strin return new DataResponse(); } + /** + * Update the initialization progress of the calling ExApp + * + * @param int $progress Initialization progress in percent (0-100) + * @param string $error Error message in case the initialization failed + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Initialization progress updated + * 404: ExApp not found + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] #[MaintenanceModeAvailable] public function setAppInitProgress(int $progress, string $error = ''): DataResponse { - $exApp = $this->exAppService->getExApp($this->request->getHeader('EX-APP-ID')); + $exApp = $this->exAppService->getExApp($this->request->getHeader('ex-app-id')); if (!$exApp) { return new DataResponse([], Http::STATUS_NOT_FOUND); } @@ -97,23 +137,36 @@ public function setAppInitProgress(int $progress, string $error = ''): DataRespo } /** - * Retrieves the enabled status of an ExApp (0 for disabled, 1 for enabled). + * Get the enabled state of the calling ExApp (0 for disabled, 1 for enabled) + * * Note: This endpoint is accessible even if the ExApp itself is disabled. * - * @return DataResponse The enabled status of the ExApp. + * @return DataResponse|DataResponse, array{}> + * + * 200: Enabled state returned + * 404: ExApp not found */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] #[MaintenanceModeAvailable] public function getEnabledState(): DataResponse { - $exApp = $this->exAppService->getExApp($this->request->getHeader('EX-APP-ID')); + $exApp = $this->exAppService->getExApp($this->request->getHeader('ex-app-id')); if (!$exApp) { return new DataResponse([], Http::STATUS_NOT_FOUND); } return new DataResponse($exApp->getEnabled()); } + /** + * Build an absolute URL from a Nextcloud-relative URL + * + * @param string $url Relative URL to convert into an absolute one + * + * @return DataResponse + * + * 200: Absolute URL returned + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] diff --git a/lib/Controller/OCSExAppController.php b/lib/Controller/OCSExAppController.php index 720a96eec..7f8cdb8cb 100644 --- a/lib/Controller/OCSExAppController.php +++ b/lib/Controller/OCSExAppController.php @@ -10,6 +10,7 @@ namespace OCA\AppAPI\Controller; use OCA\AppAPI\AppInfo\Application; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\AppAPIService; use OCA\AppAPI\Service\ExAppService; use OCP\AppFramework\Http; @@ -20,6 +21,10 @@ use OCP\IRequest; use OCP\IURLGenerator; +/** + * @psalm-import-type AppAPIExApp from ResponseDefinitions + * @psalm-import-type AppAPIExAppRequestResult from ResponseDefinitions + */ class OCSExAppController extends OCSController { protected $request; @@ -34,6 +39,16 @@ public function __construct( $this->request = $request; } + /** + * Get a list of registered ExApps + * + * @param 'all'|'enabled' $list Which ExApps to return + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: ExApps list returned + * 400: Invalid list type + */ #[NoCSRFRequired] public function getExAppsList(string $list = 'enabled'): DataResponse { if (!in_array($list, ['all', 'enabled'])) { @@ -42,6 +57,16 @@ public function getExAppsList(string $list = 'enabled'): DataResponse { return new DataResponse($this->exAppService->getExAppsList($list), Http::STATUS_OK); } + /** + * Get information about a registered ExApp + * + * @param string $appId ID of the ExApp + * + * @return DataResponse|DataResponse, array{}> + * + * 200: ExApp info returned + * 404: ExApp not found + */ #[NoCSRFRequired] public function getExApp(string $appId): DataResponse { $exApp = $this->exAppService->getExApp($appId); @@ -51,6 +76,13 @@ public function getExApp(string $appId): DataResponse { return new DataResponse($this->exAppService->formatExAppInfo($exApp), Http::STATUS_OK); } + /** + * Get the base URL of this Nextcloud instance + * + * @return DataResponse + * + * 200: Base URL returned + */ #[NoCSRFRequired] public function getNextcloudUrl(): DataResponse { return new DataResponse([ @@ -59,7 +91,16 @@ public function getNextcloudUrl(): DataResponse { } /** - * @throws OCSBadRequestException + * Enable or disable a registered ExApp + * + * @param string $appId ID of the ExApp + * @param int $enabled New state: 1 to enable, 0 to disable + * + * @return DataResponse, array{}>|DataResponse, array{}> + * @throws OCSBadRequestException ExApp is already in the requested state or the state change failed + * + * 200: ExApp state changed + * 404: ExApp not found */ #[NoCSRFRequired] public function setExAppEnabled(string $appId, int $enabled): DataResponse { @@ -87,6 +128,22 @@ public function setExAppEnabled(string $appId, int $enabled): DataResponse { return new DataResponse(); } + /** + * Proxy a request from one ExApp to another registered ExApp + * + * @param string $appId ID of the target ExApp + * @param string $route Route inside the target ExApp to call + * @param ?string $userId User to perform the request on behalf of, or null + * @param string $method HTTP method to use + * @param array $params Request parameters + * @param array $options Additional request options + * + * @return DataResponse|DataResponse + * @psalm-suppress InvalidReturnType, InvalidReturnStatement The proxied ExApp response body is dynamically typed + * + * 200: ExApp response returned + * 400: Request to the ExApp failed + */ #[NoCSRFRequired] public function requestToExApp( string $appId, @@ -112,7 +169,20 @@ public function requestToExApp( } /** - * TODO: remove later + * Proxy a request from one ExApp to another registered ExApp (deprecated alias) + * + * @param string $appId ID of the target ExApp + * @param string $route Route inside the target ExApp to call + * @param ?string $userId User to perform the request on behalf of, or null + * @param string $method HTTP method to use + * @param array $params Request parameters + * @param array $options Additional request options + * + * @return DataResponse|DataResponse + * @psalm-suppress InvalidReturnType, InvalidReturnStatement The proxied ExApp response body is dynamically typed + * + * 200: ExApp response returned + * 400: Request to the ExApp failed * * @deprecated since AppAPI 3.0.0 */ diff --git a/lib/Controller/OCSSettingsController.php b/lib/Controller/OCSSettingsController.php index 796acbc81..107a79840 100644 --- a/lib/Controller/OCSSettingsController.php +++ b/lib/Controller/OCSSettingsController.php @@ -31,36 +31,66 @@ public function __construct( $this->request = $request; } + /** + * Register a declarative settings form for the calling ExApp + * + * @param array $formScheme Declarative settings form scheme + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Settings form registered + * 400: Settings form could not be registered + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] public function registerForm(array $formScheme): DataResponse { $settingsForm = $this->settingsService->registerForm( - $this->request->getHeader('EX-APP-ID'), $formScheme); + $this->request->getHeader('ex-app-id'), $formScheme); if ($settingsForm === null) { return new DataResponse([], Http::STATUS_BAD_REQUEST); } return new DataResponse(); } + /** + * Unregister a declarative settings form of the calling ExApp + * + * @param string $formId ID of the settings form to remove + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Settings form unregistered + * 404: Settings form not found + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] public function unregisterForm(string $formId): DataResponse { $unregistered = $this->settingsService->unregisterForm( - $this->request->getHeader('EX-APP-ID'), $formId); + $this->request->getHeader('ex-app-id'), $formId); if ($unregistered === null) { return new DataResponse([], Http::STATUS_NOT_FOUND); } return new DataResponse(); } + /** + * Get a declarative settings form of the calling ExApp + * + * @param string $formId ID of the settings form + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Settings form returned + * 404: Settings form not found + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getForm(string $formId): DataResponse { $result = $this->settingsService->getForm( - $this->request->getHeader('EX-APP-ID'), $formId); + $this->request->getHeader('ex-app-id'), $formId); if (!$result) { return new DataResponse([], Http::STATUS_NOT_FOUND); } diff --git a/lib/Controller/OCSUiController.php b/lib/Controller/OCSUiController.php index 9783b21d2..0120a4145 100644 --- a/lib/Controller/OCSUiController.php +++ b/lib/Controller/OCSUiController.php @@ -11,6 +11,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\UI\FilesActionsMenuService; use OCA\AppAPI\Service\UI\InitialStateService; use OCA\AppAPI\Service\UI\ScriptsService; @@ -25,6 +26,13 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; +/** + * @psalm-import-type AppAPIFileAction from ResponseDefinitions + * @psalm-import-type AppAPITopMenu from ResponseDefinitions + * @psalm-import-type AppAPIInitialState from ResponseDefinitions + * @psalm-import-type AppAPIScript from ResponseDefinitions + * @psalm-import-type AppAPIStyle from ResponseDefinitions + */ class OCSUiController extends OCSController { protected $request; @@ -42,7 +50,20 @@ public function __construct( } /** - * @throws OCSBadRequestException + * Register a files action menu entry for the calling ExApp + * + * @param string $name Unique name of the action + * @param string $displayName Human-readable display name + * @param string $actionHandler Handler route called when the action is triggered + * @param string $icon Icon to display next to the action + * @param string $mime Mimetype the action applies to + * @param int $permissions Required permissions on the file + * @param int $order Ordering of the action in the menu + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException File action menu entry could not be registered + * + * 200: File action menu entry registered * * @deprecated since AppAPI 2.6.0, use registerFileActionMenuV2 instead */ @@ -53,7 +74,7 @@ public function registerFileActionMenu(string $name, string $displayName, string string $icon = '', string $mime = 'file', int $permissions = 31, int $order = 0): DataResponse { $result = $this->filesActionsMenuService->registerFileActionMenu( - $this->request->getHeader('EX-APP-ID'), $name, $displayName, $actionHandler, $icon, $mime, $permissions, $order, '1.0'); + $this->request->getHeader('ex-app-id'), $name, $displayName, $actionHandler, $icon, $mime, $permissions, $order, '1.0'); if (!$result) { throw new OCSBadRequestException('File Action Menu entry could not be registered'); } @@ -61,8 +82,21 @@ public function registerFileActionMenu(string $name, string $displayName, string } /** - * @param string $defaultAction One of '', 'default', or 'hidden' - * @throws OCSBadRequestException + * Register a files action menu entry (v2) for the calling ExApp + * + * @param string $name Unique name of the action + * @param string $displayName Human-readable display name + * @param string $actionHandler Handler route called when the action is triggered + * @param string $icon Icon to display next to the action + * @param string $mime Mimetype the action applies to + * @param int $permissions Required permissions on the file + * @param int $order Ordering of the action in the menu + * @param string $defaultAction Whether this is the default action: one of '', 'default' or 'hidden' + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException File action menu entry could not be registered or defaultAction is invalid + * + * 200: File action menu entry registered */ #[AppAPIAuth] #[PublicPage] @@ -74,7 +108,7 @@ public function registerFileActionMenuV2(string $name, string $displayName, stri throw new OCSBadRequestException("Invalid defaultAction '$defaultAction' — must be '', 'default', or 'hidden'"); } $result = $this->filesActionsMenuService->registerFileActionMenu( - $this->request->getHeader('EX-APP-ID'), $name, $displayName, $actionHandler, $icon, $mime, $permissions, $order, '2.0', $defaultAction ?: null); + $this->request->getHeader('ex-app-id'), $name, $displayName, $actionHandler, $icon, $mime, $permissions, $order, '2.0', $defaultAction ?: null); if (!$result) { throw new OCSBadRequestException('File Action Menu entry could not be registered'); } @@ -82,14 +116,21 @@ public function registerFileActionMenuV2(string $name, string $displayName, stri } /** - * @throws OCSNotFoundException + * Unregister a files action menu entry of the calling ExApp + * + * @param string $name Name of the action to remove + * + * @return DataResponse, array{}> + * @throws OCSNotFoundException File action menu entry not found + * + * 200: File action menu entry unregistered */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function unregisterFileActionMenu(string $name): DataResponse { $unregisteredFileActionMenu = $this->filesActionsMenuService->unregisterFileActionMenu( - $this->request->getHeader('EX-APP-ID'), $name); + $this->request->getHeader('ex-app-id'), $name); if ($unregisteredFileActionMenu === null) { throw new OCSNotFoundException('FileActionMenu not found'); } @@ -97,22 +138,39 @@ public function unregisterFileActionMenu(string $name): DataResponse { } /** - * @throws OCSNotFoundException + * Get a files action menu entry of the calling ExApp + * + * @param string $name Name of the action + * + * @return DataResponse + * @throws OCSNotFoundException File action menu entry not found + * + * 200: File action menu entry returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getFileActionMenu(string $name): DataResponse { $result = $this->filesActionsMenuService->getExAppFileAction( - $this->request->getHeader('EX-APP-ID'), $name); + $this->request->getHeader('ex-app-id'), $name); if (!$result) { throw new OCSNotFoundException('FileActionMenu not found'); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } /** - * @throws OCSBadRequestException + * Register a top menu entry for the calling ExApp + * + * @param string $name Unique name of the menu entry + * @param string $displayName Human-readable display name + * @param string $icon Icon to display for the menu entry + * @param int $adminRequired Whether the entry is only visible to admins (1) or to everyone (0) + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException Top menu entry could not be registered + * + * 200: Top menu entry registered */ #[AppAPIAuth] #[PublicPage] @@ -121,7 +179,7 @@ public function registerExAppMenuEntry( string $name, string $displayName, string $icon = '', int $adminRequired = 0): DataResponse { $result = $this->menuEntryService->registerExAppMenuEntry( - $this->request->getHeader('EX-APP-ID'), $name, $displayName, $icon, $adminRequired); + $this->request->getHeader('ex-app-id'), $name, $displayName, $icon, $adminRequired); if (!$result) { throw new OCSBadRequestException('Top Menu entry could not be registered'); } @@ -129,14 +187,21 @@ public function registerExAppMenuEntry( } /** - * @throws OCSNotFoundException + * Unregister a top menu entry of the calling ExApp + * + * @param string $name Name of the menu entry to remove + * + * @return DataResponse, array{}> + * @throws OCSNotFoundException Top menu entry not found + * + * 200: Top menu entry unregistered */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function unregisterExAppMenuEntry(string $name): DataResponse { $result = $this->menuEntryService->unregisterExAppMenuEntry( - $this->request->getHeader('EX-APP-ID'), $name); + $this->request->getHeader('ex-app-id'), $name); if (!$result) { throw new OCSNotFoundException('No such Top Menu entry'); } @@ -144,29 +209,46 @@ public function unregisterExAppMenuEntry(string $name): DataResponse { } /** - * @throws OCSNotFoundException + * Get a top menu entry of the calling ExApp + * + * @param string $name Name of the menu entry + * + * @return DataResponse + * @throws OCSNotFoundException Top menu entry not found + * + * 200: Top menu entry returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getExAppMenuEntry(string $name): DataResponse { $result = $this->menuEntryService->getExAppMenuEntry( - $this->request->getHeader('EX-APP-ID'), $name); + $this->request->getHeader('ex-app-id'), $name); if (!$result) { throw new OCSNotFoundException('No such Top Menu entry'); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } /** - * @throws OCSBadRequestException + * Set an initial state for a page of the calling ExApp + * + * @param string $type Page type the initial state belongs to + * @param string $name Name of the page + * @param string $key Initial state key + * @param array $value Initial state value + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException Initial state could not be set + * + * 200: Initial state set */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function setExAppInitialState(string $type, string $name, string $key, array $value): DataResponse { $result = $this->initialStateService->setExAppInitialState( - $this->request->getHeader('EX-APP-ID'), $type, $name, $key, $value); + $this->request->getHeader('ex-app-id'), $type, $name, $key, $value); if (!$result) { throw new OCSBadRequestException('InitialState could not be set'); } @@ -174,14 +256,23 @@ public function setExAppInitialState(string $type, string $name, string $key, ar } /** - * @throws OCSNotFoundException + * Delete an initial state of the calling ExApp + * + * @param string $type Page type the initial state belongs to + * @param string $name Name of the page + * @param string $key Initial state key + * + * @return DataResponse, array{}> + * @throws OCSNotFoundException Initial state not found + * + * 200: Initial state deleted */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function deleteExAppInitialState(string $type, string $name, string $key): DataResponse { $result = $this->initialStateService->deleteExAppInitialState( - $this->request->getHeader('EX-APP-ID'), $type, $name, $key); + $this->request->getHeader('ex-app-id'), $type, $name, $key); if (!$result) { throw new OCSNotFoundException('No such InitialState'); } @@ -189,29 +280,48 @@ public function deleteExAppInitialState(string $type, string $name, string $key) } /** - * @throws OCSNotFoundException + * Get an initial state of the calling ExApp + * + * @param string $type Page type the initial state belongs to + * @param string $name Name of the page + * @param string $key Initial state key + * + * @return DataResponse + * @throws OCSNotFoundException Initial state not found + * + * 200: Initial state returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getExAppInitialState(string $type, string $name, string $key): DataResponse { $result = $this->initialStateService->getExAppInitialState( - $this->request->getHeader('EX-APP-ID'), $type, $name, $key); + $this->request->getHeader('ex-app-id'), $type, $name, $key); if (!$result) { throw new OCSNotFoundException('No such InitialState'); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } /** - * @throws OCSBadRequestException + * Register a script for a page of the calling ExApp + * + * @param string $type Page type the script belongs to + * @param string $name Name of the page + * @param string $path Path to the script file inside the ExApp + * @param string $afterAppId Load the script after the script of this app + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException Script could not be set + * + * 200: Script registered */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function setExAppScript(string $type, string $name, string $path, string $afterAppId = ''): DataResponse { $result = $this->scriptsService->setExAppScript( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path, $afterAppId); + $this->request->getHeader('ex-app-id'), $type, $name, $path, $afterAppId); if (!$result) { throw new OCSBadRequestException('Script could not be set'); } @@ -219,14 +329,23 @@ public function setExAppScript(string $type, string $name, string $path, string } /** - * @throws OCSNotFoundException + * Delete a script of the calling ExApp + * + * @param string $type Page type the script belongs to + * @param string $name Name of the page + * @param string $path Path to the script file inside the ExApp + * + * @return DataResponse, array{}> + * @throws OCSNotFoundException Script not found + * + * 200: Script deleted */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function deleteExAppScript(string $type, string $name, string $path): DataResponse { $result = $this->scriptsService->deleteExAppScript( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path); + $this->request->getHeader('ex-app-id'), $type, $name, $path); if (!$result) { throw new OCSNotFoundException('No such Script'); } @@ -234,29 +353,47 @@ public function deleteExAppScript(string $type, string $name, string $path): Dat } /** - * @throws OCSNotFoundException + * Get a script of the calling ExApp + * + * @param string $type Page type the script belongs to + * @param string $name Name of the page + * @param string $path Path to the script file inside the ExApp + * + * @return DataResponse + * @throws OCSNotFoundException Script not found + * + * 200: Script returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getExAppScript(string $type, string $name, string $path): DataResponse { $result = $this->scriptsService->getExAppScript( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path); + $this->request->getHeader('ex-app-id'), $type, $name, $path); if (!$result) { throw new OCSNotFoundException('No such Script'); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } /** - * @throws OCSBadRequestException + * Register a style for a page of the calling ExApp + * + * @param string $type Page type the style belongs to + * @param string $name Name of the page + * @param string $path Path to the style file inside the ExApp + * + * @return DataResponse, array{}> + * @throws OCSBadRequestException Style could not be set + * + * 200: Style registered */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function setExAppStyle(string $type, string $name, string $path): DataResponse { $result = $this->stylesService->setExAppStyle( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path); + $this->request->getHeader('ex-app-id'), $type, $name, $path); if (!$result) { throw new OCSBadRequestException('Style could not be set'); } @@ -264,14 +401,23 @@ public function setExAppStyle(string $type, string $name, string $path): DataRes } /** - * @throws OCSNotFoundException + * Delete a style of the calling ExApp + * + * @param string $type Page type the style belongs to + * @param string $name Name of the page + * @param string $path Path to the style file inside the ExApp + * + * @return DataResponse, array{}> + * @throws OCSNotFoundException Style not found + * + * 200: Style deleted */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function deleteExAppStyle(string $type, string $name, string $path): DataResponse { $result = $this->stylesService->deleteExAppStyle( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path); + $this->request->getHeader('ex-app-id'), $type, $name, $path); if (!$result) { throw new OCSNotFoundException('No such Style'); } @@ -279,17 +425,26 @@ public function deleteExAppStyle(string $type, string $name, string $path): Data } /** - * @throws OCSNotFoundException + * Get a style of the calling ExApp + * + * @param string $type Page type the style belongs to + * @param string $name Name of the page + * @param string $path Path to the style file inside the ExApp + * + * @return DataResponse + * @throws OCSNotFoundException Style not found + * + * 200: Style returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getExAppStyle(string $type, string $name, string $path): DataResponse { $result = $this->stylesService->getExAppStyle( - $this->request->getHeader('EX-APP-ID'), $type, $name, $path); + $this->request->getHeader('ex-app-id'), $type, $name, $path); if (!$result) { throw new OCSNotFoundException('No such Style'); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } } diff --git a/lib/Controller/OccCommandController.php b/lib/Controller/OccCommandController.php index 60e61bcdd..080fa274d 100644 --- a/lib/Controller/OccCommandController.php +++ b/lib/Controller/OccCommandController.php @@ -11,6 +11,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\ExAppOccService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; @@ -19,6 +20,9 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; +/** + * @psalm-import-type AppAPIOccCommand from ResponseDefinitions + */ class OccCommandController extends OCSController { protected $request; @@ -31,6 +35,22 @@ public function __construct( $this->request = $request; } + /** + * Register an occ command for the calling ExApp + * + * @param string $name Name of the command + * @param string $description Description of the command + * @param string $execute_handler Handler route called when the command is executed + * @param int $hidden Whether the command is hidden from the command list (1) or not (0) + * @param list $arguments Command argument definitions + * @param list $options Command option definitions + * @param list $usages Example usages of the command + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Command registered + * 400: Command could not be registered + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] @@ -44,7 +64,7 @@ public function registerCommand( array $usages = [], ): DataResponse { $command = $this->service->registerCommand( - $this->request->getHeader('EX-APP-ID'), $name, + $this->request->getHeader('ex-app-id'), $name, $description, $hidden, $arguments, $options, $usages, $execute_handler ); if ($command === null) { @@ -53,25 +73,45 @@ public function registerCommand( return new DataResponse(); } + /** + * Unregister an occ command of the calling ExApp + * + * @param string $name Name of the command to remove + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Command unregistered + * 404: Command not found + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] public function unregisterCommand(string $name): DataResponse { - $unregistered = $this->service->unregisterCommand($this->request->getHeader('EX-APP-ID'), $name); + $unregistered = $this->service->unregisterCommand($this->request->getHeader('ex-app-id'), $name); if (!$unregistered) { return new DataResponse([], Http::STATUS_NOT_FOUND); } return new DataResponse(); } + /** + * Get an occ command of the calling ExApp + * + * @param string $name Name of the command + * + * @return DataResponse|DataResponse, array{}> + * + * 200: Command returned + * 404: Command not found + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getCommand(string $name): DataResponse { - $result = $this->service->getOccCommand($this->request->getHeader('EX-APP-ID'), $name); + $result = $this->service->getOccCommand($this->request->getHeader('ex-app-id'), $name); if (!$result) { return new DataResponse([], Http::STATUS_NOT_FOUND); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } } diff --git a/lib/Controller/PreferencesController.php b/lib/Controller/PreferencesController.php index 6aa157a8a..229225375 100644 --- a/lib/Controller/PreferencesController.php +++ b/lib/Controller/PreferencesController.php @@ -12,6 +12,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; use OCA\AppAPI\Db\ExAppPreference; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\ExAppPreferenceService; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; @@ -23,6 +24,10 @@ use OCP\IRequest; use OCP\IUserSession; +/** + * @psalm-import-type AppAPIExAppPreference from ResponseDefinitions + * @psalm-import-type AppAPIExAppConfigValue from ResponseDefinitions + */ class PreferencesController extends OCSController { protected $request; @@ -37,7 +42,16 @@ public function __construct( } /** - * @throws OCSBadRequestException + * Set a preference value for the current user and the calling ExApp + * + * @param string $configKey Preference key + * @param mixed $configValue Preference value + * @param ?int $sensitive Whether the value is sensitive and should be stored encrypted (1) or not (0) + * + * @return DataResponse + * @throws OCSBadRequestException Config key is empty or the value could not be set + * + * 200: Preference value set */ #[AppAPIAuth] #[PublicPage] @@ -47,34 +61,50 @@ public function setUserConfigValue(string $configKey, mixed $configValue, ?int $ throw new OCSBadRequestException('Config key cannot be empty'); } $userId = $this->userSession->getUser()->getUID(); - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppPreferenceService->setUserConfigValue($userId, $appId, $configKey, $configValue, $sensitive); if ($result instanceof ExAppPreference) { - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } throw new OCSBadRequestException('Failed to set user config value'); } + /** + * Get preference values of the current user for the calling ExApp + * + * @param list $configKeys Preference keys to retrieve + * + * @return DataResponse, array{}> + * + * 200: Preference values returned + */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function getUserConfigValues(array $configKeys): DataResponse { $userId = $this->userSession->getUser()->getUID(); - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppPreferenceService->getUserConfigValues($userId, $appId, $configKeys); return new DataResponse($result, Http::STATUS_OK); } /** - * @throws OCSBadRequestException - * @throws OCSNotFoundException + * Delete preference values of the current user for the calling ExApp + * + * @param list $configKeys Preference keys to delete + * + * @return DataResponse + * @throws OCSBadRequestException Failed to delete the preference values + * @throws OCSNotFoundException No matching preference values were found + * + * 200: Number of deleted preference values returned */ #[AppAPIAuth] #[PublicPage] #[NoCSRFRequired] public function deleteUserConfigValues(array $configKeys): DataResponse { $userId = $this->userSession->getUser()->getUID(); - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $result = $this->exAppPreferenceService->deleteUserConfigValues($configKeys, $userId, $appId); if ($result === -1) { throw new OCSBadRequestException('Failed to delete user config values'); diff --git a/lib/Controller/TalkBotController.php b/lib/Controller/TalkBotController.php index b541e234b..b46201d5e 100644 --- a/lib/Controller/TalkBotController.php +++ b/lib/Controller/TalkBotController.php @@ -11,6 +11,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\AppAPIService; use OCA\AppAPI\Service\ExAppService; use OCA\AppAPI\Service\TalkBotsService; @@ -27,6 +28,9 @@ use OCP\Security\Bruteforce\IThrottler; use Psr\Log\LoggerInterface; +/** + * @psalm-import-type AppAPITalkBot from ResponseDefinitions + */ class TalkBotController extends OCSController { protected $request; @@ -44,18 +48,22 @@ public function __construct( } /** - * @param string $name bot display name - * @param string $route ExApp route to post messages - * @param string $description + * Register a Talk bot for the calling ExApp + * + * @param string $name Bot display name + * @param string $route ExApp route that receives bot messages + * @param string $description Description of the bot * - * @throws OCSBadRequestException - * @return Response + * @return DataResponse + * @throws OCSBadRequestException Talk bot could not be registered + * + * 200: Talk bot registered */ #[AppAPIAuth] #[NoCSRFRequired] #[PublicPage] public function registerExAppTalkBot(string $name, string $route, string $description): Response { - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $exApp = $this->service->getExApp($appId); $botRegistered = $this->talkBotsService->registerExAppBot( $exApp, @@ -70,13 +78,20 @@ public function registerExAppTalkBot(string $name, string $route, string $descri } /** - * @throws OCSNotFoundException + * Unregister a Talk bot of the calling ExApp + * + * @param string $route ExApp route of the bot to remove + * + * @return DataResponse + * @throws OCSNotFoundException Talk bot could not be unregistered + * + * 200: Talk bot unregistered */ #[AppAPIAuth] #[NoCSRFRequired] #[PublicPage] public function unregisterExAppTalkBot(string $route): Response { - $appId = $this->request->getHeader('EX-APP-ID'); + $appId = $this->request->getHeader('ex-app-id'); $exApp = $this->service->getExApp($appId); $botUnregistered = $this->talkBotsService->unregisterExAppBot($exApp, ltrim($route, '/')); if ($botUnregistered === null) { @@ -85,6 +100,18 @@ public function unregisterExAppTalkBot(string $route): Response { return new DataResponse($botUnregistered); } + /** + * Proxy a Talk chat message to the bot of a registered ExApp + * + * @param string $appId ID of the ExApp owning the bot + * @param string $route ExApp route that receives the message + * + * @return DataResponse, array{}>|DataResponse, array{}>|DataResponse, array{}> + * + * 200: Message proxied to the ExApp bot + * 404: Invalid signature or unknown bot + * 500: The ExApp bot could not be reached + */ #[NoAdminRequired] #[NoCSRFRequired] #[PublicPage] @@ -97,9 +124,9 @@ public function proxyTalkMessage(string $appId, string $route): Response { if ($bot_secret !== null) { $digest = hash_hmac( 'sha256', - $this->request->getHeader('X-Nextcloud-Talk-Random') . file_get_contents('php://input'), + $this->request->getHeader('x-nextcloud-talk-random') . file_get_contents('php://input'), $bot_secret); - if (!hash_equals($digest, strtolower($this->request->getHeader('X-Nextcloud-Talk-Signature')))) { + if (!hash_equals($digest, strtolower($this->request->getHeader('x-nextcloud-talk-signature')))) { $this->throttler->registerAttempt( Application::APP_ID, $this->request->getRemoteAddress(), diff --git a/lib/Controller/TaskProcessingController.php b/lib/Controller/TaskProcessingController.php index 1e4a7e2d0..b5c33bb80 100644 --- a/lib/Controller/TaskProcessingController.php +++ b/lib/Controller/TaskProcessingController.php @@ -11,6 +11,7 @@ use OCA\AppAPI\AppInfo\Application; use OCA\AppAPI\Attribute\AppAPIAuth; +use OCA\AppAPI\ResponseDefinitions; use OCA\AppAPI\Service\AppAPIService; use OCA\AppAPI\Service\ExAppService; use OCA\AppAPI\Service\ProvidersAI\TaskProcessingService; @@ -22,6 +23,9 @@ use OCP\AppFramework\OCSController; use OCP\IRequest; +/** + * @psalm-import-type AppAPITaskProcessingProvider from ResponseDefinitions + */ class TaskProcessingController extends OCSController { protected $request; @@ -38,6 +42,17 @@ public function __construct( $this->taskProcessingService->setExAppService($this->exAppService); } + /** + * Register a Task Processing provider for the calling ExApp + * + * @param array $provider Task Processing provider definition + * @param array|null $customTaskType Custom task type definition, or null + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Provider registered + * 400: Provider could not be registered + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] @@ -46,7 +61,7 @@ public function registerProvider( ?array $customTaskType, ): DataResponse { $providerObj = $this->taskProcessingService->registerTaskProcessingProvider( - $this->request->getHeader('EX-APP-ID'), + $this->request->getHeader('ex-app-id'), $provider, $customTaskType, ); @@ -58,12 +73,22 @@ public function registerProvider( return new DataResponse(); } + /** + * Unregister a Task Processing provider of the calling ExApp + * + * @param string $name Name of the provider to remove + * + * @return DataResponse, array{}>|DataResponse, array{}> + * + * 200: Provider unregistered + * 404: Provider not found + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] public function unregisterProvider(string $name): Response { $unregistered = $this->taskProcessingService->unregisterTaskProcessingProvider( - $this->request->getHeader('EX-APP-ID'), $name + $this->request->getHeader('ex-app-id'), $name ); if ($unregistered === null) { @@ -73,16 +98,26 @@ public function unregisterProvider(string $name): Response { return new DataResponse(); } + /** + * Get a Task Processing provider of the calling ExApp + * + * @param string $name Name of the provider + * + * @return DataResponse|DataResponse, array{}> + * + * 200: Provider returned + * 404: Provider not found + */ #[NoCSRFRequired] #[PublicPage] #[AppAPIAuth] public function getProvider(string $name): DataResponse { $result = $this->taskProcessingService->getExAppTaskProcessingProvider( - $this->request->getHeader('EX-APP-ID'), $name + $this->request->getHeader('ex-app-id'), $name ); if (!$result) { return new DataResponse([], Http::STATUS_NOT_FOUND); } - return new DataResponse($result, Http::STATUS_OK); + return new DataResponse($result->jsonSerialize(), Http::STATUS_OK); } } diff --git a/lib/Controller/TopMenuController.php b/lib/Controller/TopMenuController.php index 866c9c4af..8e60fe297 100644 --- a/lib/Controller/TopMenuController.php +++ b/lib/Controller/TopMenuController.php @@ -18,6 +18,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; +use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\TemplateResponse; @@ -26,6 +27,7 @@ use OCP\IGroupManager; use OCP\IRequest; +#[OpenAPI(OpenAPI::SCOPE_IGNORE)] class TopMenuController extends Controller { public bool $postprocess = false; diff --git a/lib/Db/Console/ExAppOccCommand.php b/lib/Db/Console/ExAppOccCommand.php index 1e79c596d..ddd17389e 100644 --- a/lib/Db/Console/ExAppOccCommand.php +++ b/lib/Db/Console/ExAppOccCommand.php @@ -33,6 +33,8 @@ * @method void setOptions(array $options) * @method void setUsages(array $usages) * @method void setExecuteHandler(string $executeHandler) + * + * @psalm-import-type AppAPIOccCommand from \OCA\AppAPI\ResponseDefinitions */ class ExAppOccCommand extends Entity implements JsonSerializable { protected $appid; @@ -88,6 +90,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIOccCommand + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/DaemonConfig.php b/lib/Db/DaemonConfig.php index 0824bf4ca..8d5981915 100644 --- a/lib/Db/DaemonConfig.php +++ b/lib/Db/DaemonConfig.php @@ -17,12 +17,14 @@ * * @package OCA\AppAPI\Db * + * @psalm-import-type AppAPIDaemonConfig from \OCA\AppAPI\ResponseDefinitions + * * @method string getAcceptsDeployId() * @method string getName() * @method string getDisplayName() * @method string getProtocol() * @method string getHost() - * @method array getDeployConfig() + * @method array getDeployConfig() * @method void setAcceptsDeployId(string $acceptsDeployId) * @method void setName(string $name) * @method void setDisplayName(string $displayName) @@ -72,6 +74,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIDaemonConfig + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/ExApp.php b/lib/Db/ExApp.php index 71029f122..285ee9b74 100644 --- a/lib/Db/ExApp.php +++ b/lib/Db/ExApp.php @@ -17,6 +17,8 @@ * * @package OCA\AppAPI\Db * + * @psalm-import-type AppAPIExAppStatus from \OCA\AppAPI\ResponseDefinitions + * * @method string getAppid() * @method string getVersion() * @method string getName() @@ -25,7 +27,7 @@ * @method string getHost() * @method int getPort() * @method string getSecret() - * @method array getStatus() + * @method AppAPIExAppStatus getStatus() * @method int getEnabled() * @method int getCreatedTime() * @method array getDeployConfig() diff --git a/lib/Db/ExAppConfig.php b/lib/Db/ExAppConfig.php index 57647f2bd..aeb0d4add 100644 --- a/lib/Db/ExAppConfig.php +++ b/lib/Db/ExAppConfig.php @@ -20,6 +20,8 @@ * * The `id` field has no surrogate key anymore (the server table uses a composite primary key); * it is kept in the serialized shape as `0` for backwards compatibility and is unused. + * + * @psalm-import-type AppAPIExAppConfig from \OCA\AppAPI\ResponseDefinitions */ class ExAppConfig implements JsonSerializable { private int $id; @@ -64,6 +66,9 @@ public function setSensitive(int $sensitive): void { $this->sensitive = $sensitive; } + /** + * @return AppAPIExAppConfig + */ public function jsonSerialize(): array { return [ 'id' => $this->id, diff --git a/lib/Db/ExAppPreference.php b/lib/Db/ExAppPreference.php index 944e25251..646ab7738 100644 --- a/lib/Db/ExAppPreference.php +++ b/lib/Db/ExAppPreference.php @@ -20,6 +20,8 @@ * * The `id` field has no surrogate key anymore (the server table uses a composite primary key); * it is kept in the serialized shape as `0` for backwards compatibility and is unused. + * + * @psalm-import-type AppAPIExAppPreference from \OCA\AppAPI\ResponseDefinitions */ class ExAppPreference implements JsonSerializable { private int $id; @@ -70,6 +72,9 @@ public function setSensitive(int $sensitive): void { $this->sensitive = $sensitive; } + /** + * @return AppAPIExAppPreference + */ public function jsonSerialize(): array { return [ 'id' => $this->id, diff --git a/lib/Db/TaskProcessing/TaskProcessingProvider.php b/lib/Db/TaskProcessing/TaskProcessingProvider.php index a3ffdec97..27974c37f 100644 --- a/lib/Db/TaskProcessing/TaskProcessingProvider.php +++ b/lib/Db/TaskProcessing/TaskProcessingProvider.php @@ -29,6 +29,8 @@ * @method string getProvider() * @method void setCustomTaskType(string|null $customTaskType) * @method string|null getCustomTaskType() + * + * @psalm-import-type AppAPITaskProcessingProvider from \OCA\AppAPI\ResponseDefinitions */ class TaskProcessingProvider extends Entity implements JsonSerializable { protected ?string $appId = null; @@ -69,6 +71,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPITaskProcessingProvider + */ public function jsonSerialize(): array { return [ 'id' => $this->id, diff --git a/lib/Db/UI/FilesActionsMenu.php b/lib/Db/UI/FilesActionsMenu.php index 7d3cad256..7850d63ee 100644 --- a/lib/Db/UI/FilesActionsMenu.php +++ b/lib/Db/UI/FilesActionsMenu.php @@ -37,6 +37,8 @@ * @method void setActionHandler(string $actionHandler) * @method void setVersion(string $version) * @method void setDefaultAction(string|null $defaultAction) + * + * @psalm-import-type AppAPIFileAction from \OCA\AppAPI\ResponseDefinitions */ class FilesActionsMenu extends Entity implements JsonSerializable { protected $appid; @@ -100,6 +102,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIFileAction + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/UI/InitialState.php b/lib/Db/UI/InitialState.php index a80b60203..3e244e50a 100644 --- a/lib/Db/UI/InitialState.php +++ b/lib/Db/UI/InitialState.php @@ -27,6 +27,8 @@ * @method void setName(string $name) * @method void setKey(string $key) * @method void setValue(array $value) + * + * @psalm-import-type AppAPIInitialState from \OCA\AppAPI\ResponseDefinitions */ class InitialState extends Entity implements JsonSerializable { protected $appid; @@ -65,6 +67,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIInitialState + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/UI/Script.php b/lib/Db/UI/Script.php index e8d2979d3..a5d2ff4e6 100644 --- a/lib/Db/UI/Script.php +++ b/lib/Db/UI/Script.php @@ -27,6 +27,8 @@ * @method void setName(string $name) * @method void setPath(string $path) * @method void setAfterAppId(string $afterAppId) + * + * @psalm-import-type AppAPIScript from \OCA\AppAPI\ResponseDefinitions */ class Script extends Entity implements JsonSerializable { protected $appid; @@ -65,6 +67,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIScript + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/UI/Style.php b/lib/Db/UI/Style.php index bcd685df1..9bf01da3e 100644 --- a/lib/Db/UI/Style.php +++ b/lib/Db/UI/Style.php @@ -25,6 +25,8 @@ * @method void setType(string $type) * @method void setName(string $name) * @method void setPath(string $path) + * + * @psalm-import-type AppAPIStyle from \OCA\AppAPI\ResponseDefinitions */ class Style extends Entity implements JsonSerializable { protected $appid; @@ -58,6 +60,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPIStyle + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/Db/UI/TopMenu.php b/lib/Db/UI/TopMenu.php index a1344a462..824466080 100644 --- a/lib/Db/UI/TopMenu.php +++ b/lib/Db/UI/TopMenu.php @@ -27,6 +27,8 @@ * @method void setDisplayName(string $displayName) * @method void setIcon(string $icon) * @method void setAdminRequired(int $adminRequired) + * + * @psalm-import-type AppAPITopMenu from \OCA\AppAPI\ResponseDefinitions */ class TopMenu extends Entity implements JsonSerializable { protected $appid; @@ -65,6 +67,9 @@ public function __construct(array $params = []) { } } + /** + * @return AppAPITopMenu + */ public function jsonSerialize(): array { return [ 'id' => $this->getId(), diff --git a/lib/PublicCapabilities.php b/lib/PublicCapabilities.php index 174c790f6..9f05d9d20 100644 --- a/lib/PublicCapabilities.php +++ b/lib/PublicCapabilities.php @@ -20,6 +20,9 @@ public function __construct( ) { } + /** + * @return array{app_api: array{version: string}} + */ public function getCapabilities(): array { $capabilities = [ 'version' => $this->appManager->getAppVersion(Application::APP_ID), diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php new file mode 100644 index 000000000..997a09473 --- /dev/null +++ b/lib/ResponseDefinitions.php @@ -0,0 +1,185 @@ +, + * body: string, + * } + * + * @psalm-type AppAPIFileAction = array{ + * id: int, + * appid: string, + * name: string, + * display_name: string, + * mime: string, + * permissions: string, + * order: int, + * icon: string, + * action_handler: string, + * version: string, + * default_action: ?string, + * } + * + * @psalm-type AppAPITopMenu = array{ + * id: int, + * appid: string, + * name: string, + * display_name: string, + * icon: string, + * admin_required: int, + * } + * + * @psalm-type AppAPIInitialState = array{ + * id: int, + * appid: string, + * type: string, + * name: string, + * key: string, + * value: mixed, + * } + * + * @psalm-type AppAPIScript = array{ + * id: int, + * appid: string, + * type: string, + * name: string, + * path: string, + * after_app_id: string, + * } + * + * @psalm-type AppAPIStyle = array{ + * id: int, + * appid: string, + * type: string, + * name: string, + * path: string, + * } + * + * @psalm-type AppAPITaskProcessingProvider = array{ + * id: ?int, + * app_id: ?string, + * name: ?string, + * display_name: ?string, + * task_type: ?string, + * provider: ?string, + * custom_task_type: ?string, + * } + * + * @psalm-type AppAPIOccCommand = array{ + * id: int, + * appid: string, + * name: string, + * description: string, + * hidden: int, + * arguments: list, + * options: list, + * usages: list, + * execute_handler: string, + * } + * + * @psalm-type AppAPITalkBot = array{ + * id: string, + * secret: string, + * } + * + * @psalm-type AppAPINotification = array{ + * app: string, + * user: string, + * datetime: string, + * object_type: string, + * object_id: string, + * subject: string, + * message: string, + * link: string, + * icon: string, + * } + * + * @psalm-type AppAPIDaemonConfig = array{ + * id: int, + * accepts_deploy_id: string, + * name: string, + * display_name: string, + * protocol: string, + * host: string, + * deploy_config: array, + * } + * + * @psalm-type AppAPIDaemonConfigWithAppsCount = array{ + * id: int, + * accepts_deploy_id: string, + * name: string, + * display_name: string, + * protocol: string, + * host: string, + * deploy_config: array, + * exAppsCount: int, + * } + * + * @psalm-type AppAPICategory = array{ + * id: string, + * ident: string, + * displayName: string, + * } + * + * @psalm-type AppAPIDeployOptions = array{ + * environment_variables: array, + * mounts: list, + * } + */ +class ResponseDefinitions { +} diff --git a/openapi-administration.json b/openapi-administration.json new file mode 100644 index 000000000..ec23fd0df --- /dev/null +++ b/openapi-administration.json @@ -0,0 +1,3953 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "app_api-administration", + "version": "0.0.1", + "description": "Nextcloud AppAPI", + "license": { + "name": "agpl" + } + }, + "components": { + "securitySchemes": { + "basic_auth": { + "type": "http", + "scheme": "basic" + }, + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "Capabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "loglevel", + "version" + ], + "properties": { + "loglevel": { + "type": "integer", + "format": "int64" + }, + "version": { + "type": "string" + } + } + } + } + }, + "Category": { + "type": "object", + "required": [ + "id", + "ident", + "displayName" + ], + "properties": { + "id": { + "type": "string" + }, + "ident": { + "type": "string" + }, + "displayName": { + "type": "string" + } + } + }, + "DaemonConfig": { + "type": "object", + "required": [ + "id", + "accepts_deploy_id", + "name", + "display_name", + "protocol", + "host", + "deploy_config" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "accepts_deploy_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "host": { + "type": "string" + }, + "deploy_config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "DaemonConfigWithAppsCount": { + "type": "object", + "required": [ + "id", + "accepts_deploy_id", + "name", + "display_name", + "protocol", + "host", + "deploy_config", + "exAppsCount" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "accepts_deploy_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "host": { + "type": "string" + }, + "deploy_config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "exAppsCount": { + "type": "integer", + "format": "int64" + } + } + }, + "DeployOptions": { + "type": "object", + "required": [ + "environment_variables", + "mounts" + ], + "properties": { + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "mounts": { + "type": "array", + "items": { + "type": "object", + "required": [ + "hostPath", + "containerPath", + "readonly" + ], + "properties": { + "hostPath": { + "type": "string" + }, + "containerPath": { + "type": "string" + }, + "readonly": { + "type": "boolean" + } + } + } + } + } + }, + "ExApp": { + "type": "object", + "required": [ + "id", + "name", + "version", + "enabled", + "status" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "status": { + "$ref": "#/components/schemas/ExAppStatus" + } + } + }, + "ExAppRequestResult": { + "type": "object", + "required": [ + "status_code", + "headers", + "body" + ], + "properties": { + "status_code": { + "type": "integer", + "format": "int64" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "body": { + "type": "string" + } + } + }, + "ExAppStatus": { + "type": "object", + "required": [ + "deploy", + "init", + "action", + "type", + "error" + ], + "properties": { + "deploy": { + "type": "integer", + "format": "int64" + }, + "init": { + "type": "integer", + "format": "int64" + }, + "action": { + "type": "string" + }, + "type": { + "type": "string" + }, + "error": { + "type": "string" + }, + "deploy_start_time": { + "type": "integer", + "format": "int64" + }, + "init_start_time": { + "type": "integer", + "format": "int64" + }, + "heartbeat_count": { + "type": "integer", + "format": "int64" + } + } + }, + "OCSMeta": { + "type": "object", + "required": [ + "status", + "statuscode" + ], + "properties": { + "status": { + "type": "string" + }, + "statuscode": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "totalitems": { + "type": "string" + }, + "itemsperpage": { + "type": "string" + } + } + }, + "PublicCapabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string" + } + } + } + } + } + } + }, + "paths": { + "/index.php/apps/app_api/admin-config": { + "put": { + "operationId": "config-set-admin-config", + "summary": "Update the AppAPI admin configuration", + "description": "This endpoint requires admin access", + "tags": [ + "config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "values" + ], + "properties": { + "values": { + "type": "object", + "description": "Configuration key-value pairs to store", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Configuration updated", + "content": { + "application/json": { + "schema": { + "type": "integer", + "format": "int64" + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/categories": { + "get": { + "operationId": "ex_apps_page-list-categories", + "summary": "Get all available App Store categories", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Categories returned", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Category" + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/list": { + "get": { + "operationId": "ex_apps_page-list-apps", + "summary": "Get the list of ExApps available in the App Store together with locally installed ones", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "responses": { + "200": { + "description": "ExApps list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "apps", + "status" + ], + "properties": { + "apps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + }, + "status": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/enable/{appId}/{daemonId}": { + "get": { + "operationId": "ex_apps_page-enable-app-get", + "summary": "Deploy and enable, or just enable, an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "daemonId", + "in": "path", + "description": "Name of the deploy daemon to use", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "deployOptions", + "in": "query", + "description": "Deploy options (environment variables, mounts)", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "update_required": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "500": { + "description": "ExApp could not be enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "ex_apps_page-enable-app", + "summary": "Deploy and enable, or just enable, an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deployOptions": { + "type": "object", + "default": {}, + "description": "Deploy options (environment variables, mounts)", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "daemonId", + "in": "path", + "description": "Name of the deploy daemon to use", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "update_required": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "500": { + "description": "ExApp could not be enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/status/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-status", + "summary": "Get the status of an ExApp, including its initialization information", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExApp status returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/logs/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-logs", + "summary": "Download the container logs of an ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "tail", + "in": "query", + "description": "Number of lines to return from the end of the logs, or 'all'", + "schema": { + "type": "string", + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "ExApp logs returned", + "content": { + "text/plain": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/deploy-options/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-deploy-options", + "summary": "Get the deploy options of an ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Deploy options returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployOptions" + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/disable/{appId}": { + "get": { + "operationId": "ex_apps_page-disable-app", + "summary": "Disable an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp disabled", + "content": { + "application/json": { + "schema": {} + } + } + }, + "500": { + "description": "ExApp could not be disabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/update/{appId}": { + "get": { + "operationId": "ex_apps_page-update-app", + "summary": "Update an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExApp updated", + "content": { + "application/json": { + "schema": {} + } + } + }, + "500": { + "description": "ExApp could not be updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/uninstall/{appId}": { + "get": { + "operationId": "ex_apps_page-uninstall-app", + "summary": "Unregister an ExApp and optionally remove its container and data", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "removeContainer", + "in": "query", + "description": "Whether to remove the ExApp container", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "removeData", + "in": "query", + "description": "Whether to remove the ExApp data volume", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp uninstalled", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/force": { + "post": { + "operationId": "ex_apps_page-force", + "summary": "Mark an ExApp as compatible with the current Nextcloud version", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "appId" + ], + "properties": { + "appId": { + "type": "string", + "description": "ID of the ExApp" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Compatibility requirement overwritten", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons": { + "get": { + "operationId": "daemon_config-get-all-daemon-configs", + "summary": "Get all registered deploy daemons together with the number of ExApps each one runs", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemons returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemons", + "default_daemon_config" + ], + "properties": { + "daemons": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DaemonConfigWithAppsCount" + } + }, + "default_daemon_config": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "daemon_config-register-daemon-config", + "summary": "Register a new deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonConfigParams" + ], + "properties": { + "daemonConfigParams": { + "type": "object", + "description": "Daemon configuration parameters", + "additionalProperties": { + "type": "object" + } + }, + "defaultDaemon": { + "type": "boolean", + "default": false, + "description": "Whether to set the new daemon as the default one" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}": { + "delete": { + "operationId": "daemon_config-unregister-daemon-config", + "summary": "Unregister a deploy daemon and remove the ExApps that run on it", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "put": { + "operationId": "daemon_config-update-daemon-config", + "summary": "Update a registered deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonConfigParams" + ], + "properties": { + "daemonConfigParams": { + "type": "object", + "description": "New daemon configuration parameters", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to update", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/check": { + "post": { + "operationId": "daemon_config-verify-daemon-connection", + "summary": "Verify the connection to a registered deploy daemon", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to check", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Connection check result returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/verify_connection": { + "post": { + "operationId": "daemon_config-check-daemon-connection", + "summary": "Check the connection to a deploy daemon from the given parameters", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonParams" + ], + "properties": { + "daemonParams": { + "type": "object", + "description": "Daemon parameters to check", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Connection check result returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/add-registry": { + "post": { + "operationId": "daemon_config-add-daemon-docker-registry", + "summary": "Add a Docker registry mapping to a deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "registryMap" + ], + "properties": { + "registryMap": { + "type": "object", + "description": "Docker registry mapping to add", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Registry added", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DaemonConfig" + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Registry could not be added", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/remove-registry": { + "post": { + "operationId": "daemon_config-remove-daemon-docker-registry", + "summary": "Remove a Docker registry mapping from a deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "registryMap" + ], + "properties": { + "registryMap": { + "type": "object", + "description": "Docker registry mapping to remove", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Registry removed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DaemonConfig" + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Registry could not be removed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/test_deploy": { + "post": { + "operationId": "daemon_config-start-test-deploy", + "summary": "Start a test deployment on a deploy daemon", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to deploy on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy started", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Test deploy could not be started", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "daemon_config-stop-test-deploy", + "summary": "Stop the running test deployment", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon the test runs on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy stopped", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/test_deploy/status": { + "get": { + "operationId": "daemon_config-get-test-deploy-status", + "summary": "Get the status of the running test deployment", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon the test runs on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy status returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "404": { + "description": "Test ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/info/nextcloud_url": { + "get": { + "operationId": "ocs_ex_app-get-nextcloud-url", + "summary": "Get the base URL of this Nextcloud instance", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Base URL returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "base_url" + ], + "properties": { + "base_url": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/{list}": { + "get": { + "operationId": "ocs_ex_app-get-ex-apps-list", + "summary": "Get a list of registered ExApps", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "list", + "in": "path", + "description": "Which ExApps to return", + "required": true, + "schema": { + "type": "string", + "default": "enabled", + "enum": [ + "all", + "enabled" + ] + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApps list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExApp" + } + } + } + } + } + } + } + } + }, + "400": { + "description": "Invalid list type", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/info/{appId}": { + "get": { + "operationId": "ocs_ex_app-get-ex-app", + "summary": "Get information about a registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp info returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExApp" + } + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/request/{appId}": { + "post": { + "operationId": "ocs_ex_app-request-to-ex-app", + "summary": "Proxy a request from one ExApp to another registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "type": "string", + "description": "Route inside the target ExApp to call" + }, + "userId": { + "type": "string", + "nullable": true, + "default": null, + "description": "User to perform the request on behalf of, or null" + }, + "method": { + "type": "string", + "default": "POST", + "description": "HTTP method to use" + }, + "params": { + "type": "object", + "default": {}, + "description": "Request parameters", + "additionalProperties": { + "type": "object" + } + }, + "options": { + "type": "object", + "default": {}, + "description": "Additional request options", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the target ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp response returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExAppRequestResult" + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + }, + "400": { + "description": "Request to the ExApp failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/request/{appId}/{$userId}": { + "post": { + "operationId": "ocs_ex_app-ae-request-to-ex-app", + "summary": "Proxy a request from one ExApp to another registered ExApp (deprecated alias)", + "description": "This endpoint requires admin access", + "deprecated": true, + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "type": "string", + "description": "Route inside the target ExApp to call" + }, + "userId": { + "type": "string", + "nullable": true, + "default": null, + "description": "User to perform the request on behalf of, or null" + }, + "method": { + "type": "string", + "default": "POST", + "description": "HTTP method to use" + }, + "params": { + "type": "object", + "default": {}, + "description": "Request parameters", + "additionalProperties": { + "type": "object" + } + }, + "options": { + "type": "object", + "default": {}, + "description": "Additional request options", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the target ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "$userId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp response returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExAppRequestResult" + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + }, + "400": { + "description": "Request to the ExApp failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/{appId}/enabled": { + "put": { + "operationId": "ocs_ex_app-set-ex-app-enabled", + "summary": "Enable or disable a registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "enabled" + ], + "properties": { + "enabled": { + "type": "integer", + "format": "int64", + "description": "New state: 1 to enable, 0 to disable" + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp state changed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "ExApp is already in the requested state or the state change failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + } + }, + "tags": [ + { + "name": "ex_apps_page", + "description": "ExApps actions controller similar to default one with project-specific changes and additions" + }, + { + "name": "daemon_config", + "description": "DaemonConfig actions (for UI)" + } + ] +} diff --git a/openapi-full.json b/openapi-full.json new file mode 100644 index 000000000..98a6ed6a2 --- /dev/null +++ b/openapi-full.json @@ -0,0 +1,9131 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "app_api-full", + "version": "0.0.1", + "description": "Nextcloud AppAPI", + "license": { + "name": "agpl" + } + }, + "components": { + "securitySchemes": { + "basic_auth": { + "type": "http", + "scheme": "basic" + }, + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "Capabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "loglevel", + "version" + ], + "properties": { + "loglevel": { + "type": "integer", + "format": "int64" + }, + "version": { + "type": "string" + } + } + } + } + }, + "Category": { + "type": "object", + "required": [ + "id", + "ident", + "displayName" + ], + "properties": { + "id": { + "type": "string" + }, + "ident": { + "type": "string" + }, + "displayName": { + "type": "string" + } + } + }, + "DaemonConfig": { + "type": "object", + "required": [ + "id", + "accepts_deploy_id", + "name", + "display_name", + "protocol", + "host", + "deploy_config" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "accepts_deploy_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "host": { + "type": "string" + }, + "deploy_config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + }, + "DaemonConfigWithAppsCount": { + "type": "object", + "required": [ + "id", + "accepts_deploy_id", + "name", + "display_name", + "protocol", + "host", + "deploy_config", + "exAppsCount" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "accepts_deploy_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "protocol": { + "type": "string" + }, + "host": { + "type": "string" + }, + "deploy_config": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "exAppsCount": { + "type": "integer", + "format": "int64" + } + } + }, + "DeployOptions": { + "type": "object", + "required": [ + "environment_variables", + "mounts" + ], + "properties": { + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "mounts": { + "type": "array", + "items": { + "type": "object", + "required": [ + "hostPath", + "containerPath", + "readonly" + ], + "properties": { + "hostPath": { + "type": "string" + }, + "containerPath": { + "type": "string" + }, + "readonly": { + "type": "boolean" + } + } + } + } + } + }, + "ExApp": { + "type": "object", + "required": [ + "id", + "name", + "version", + "enabled", + "status" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "status": { + "$ref": "#/components/schemas/ExAppStatus" + } + } + }, + "ExAppConfig": { + "type": "object", + "required": [ + "id", + "appid", + "configkey", + "configvalue", + "sensitive" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + }, + "sensitive": { + "type": "integer", + "format": "int64" + } + } + }, + "ExAppConfigValue": { + "type": "object", + "required": [ + "configkey", + "configvalue" + ], + "properties": { + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + } + } + }, + "ExAppPreference": { + "type": "object", + "required": [ + "id", + "user_id", + "appid", + "configkey", + "configvalue", + "sensitive" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "user_id": { + "type": "string" + }, + "appid": { + "type": "string" + }, + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + }, + "sensitive": { + "type": "integer", + "format": "int64" + } + } + }, + "ExAppRequestResult": { + "type": "object", + "required": [ + "status_code", + "headers", + "body" + ], + "properties": { + "status_code": { + "type": "integer", + "format": "int64" + }, + "headers": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "body": { + "type": "string" + } + } + }, + "ExAppStatus": { + "type": "object", + "required": [ + "deploy", + "init", + "action", + "type", + "error" + ], + "properties": { + "deploy": { + "type": "integer", + "format": "int64" + }, + "init": { + "type": "integer", + "format": "int64" + }, + "action": { + "type": "string" + }, + "type": { + "type": "string" + }, + "error": { + "type": "string" + }, + "deploy_start_time": { + "type": "integer", + "format": "int64" + }, + "init_start_time": { + "type": "integer", + "format": "int64" + }, + "heartbeat_count": { + "type": "integer", + "format": "int64" + } + } + }, + "FileAction": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "display_name", + "mime", + "permissions", + "order", + "icon", + "action_handler", + "version", + "default_action" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "mime": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "order": { + "type": "integer", + "format": "int64" + }, + "icon": { + "type": "string" + }, + "action_handler": { + "type": "string" + }, + "version": { + "type": "string" + }, + "default_action": { + "type": "string", + "nullable": true + } + } + }, + "InitialState": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "key", + "value" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "object" + } + } + }, + "Notification": { + "type": "object", + "required": [ + "app", + "user", + "datetime", + "object_type", + "object_id", + "subject", + "message", + "link", + "icon" + ], + "properties": { + "app": { + "type": "string" + }, + "user": { + "type": "string" + }, + "datetime": { + "type": "string" + }, + "object_type": { + "type": "string" + }, + "object_id": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "message": { + "type": "string" + }, + "link": { + "type": "string" + }, + "icon": { + "type": "string" + } + } + }, + "OCSMeta": { + "type": "object", + "required": [ + "status", + "statuscode" + ], + "properties": { + "status": { + "type": "string" + }, + "statuscode": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "totalitems": { + "type": "string" + }, + "itemsperpage": { + "type": "string" + } + } + }, + "OccCommand": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "description", + "hidden", + "arguments", + "options", + "usages", + "execute_handler" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "integer", + "format": "int64" + }, + "arguments": { + "type": "array", + "items": { + "type": "object" + } + }, + "options": { + "type": "array", + "items": { + "type": "object" + } + }, + "usages": { + "type": "array", + "items": { + "type": "object" + } + }, + "execute_handler": { + "type": "string" + } + } + }, + "PublicCapabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string" + } + } + } + } + }, + "Script": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "path", + "after_app_id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "after_app_id": { + "type": "string" + } + } + }, + "Style": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "path" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, + "TalkBot": { + "type": "object", + "required": [ + "id", + "secret" + ], + "properties": { + "id": { + "type": "string" + }, + "secret": { + "type": "string" + } + } + }, + "TaskProcessingProvider": { + "type": "object", + "required": [ + "id", + "app_id", + "name", + "display_name", + "task_type", + "provider", + "custom_task_type" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "app_id": { + "type": "string", + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "display_name": { + "type": "string", + "nullable": true + }, + "task_type": { + "type": "string", + "nullable": true + }, + "provider": { + "type": "string", + "nullable": true + }, + "custom_task_type": { + "type": "string", + "nullable": true + } + } + }, + "TopMenu": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "display_name", + "icon", + "admin_required" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "admin_required": { + "type": "integer", + "format": "int64" + } + } + } + } + }, + "paths": { + "/index.php/apps/app_api/admin-config": { + "put": { + "operationId": "config-set-admin-config", + "summary": "Update the AppAPI admin configuration", + "description": "This endpoint requires admin access", + "tags": [ + "config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "values" + ], + "properties": { + "values": { + "type": "object", + "description": "Configuration key-value pairs to store", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Configuration updated", + "content": { + "application/json": { + "schema": { + "type": "integer", + "format": "int64" + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/categories": { + "get": { + "operationId": "ex_apps_page-list-categories", + "summary": "Get all available App Store categories", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Categories returned", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Category" + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/list": { + "get": { + "operationId": "ex_apps_page-list-apps", + "summary": "Get the list of ExApps available in the App Store together with locally installed ones", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "responses": { + "200": { + "description": "ExApps list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "apps", + "status" + ], + "properties": { + "apps": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + }, + "status": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/enable/{appId}/{daemonId}": { + "get": { + "operationId": "ex_apps_page-enable-app-get", + "summary": "Deploy and enable, or just enable, an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "daemonId", + "in": "path", + "description": "Name of the deploy daemon to use", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "deployOptions", + "in": "query", + "description": "Deploy options (environment variables, mounts)", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "update_required": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "500": { + "description": "ExApp could not be enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "ex_apps_page-enable-app", + "summary": "Deploy and enable, or just enable, an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deployOptions": { + "type": "object", + "default": {}, + "description": "Deploy options (environment variables, mounts)", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "daemonId", + "in": "path", + "description": "Name of the deploy daemon to use", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "data": { + "type": "object", + "properties": { + "update_required": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "500": { + "description": "ExApp could not be enabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/status/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-status", + "summary": "Get the status of an ExApp, including its initialization information", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExApp status returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/logs/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-logs", + "summary": "Download the container logs of an ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "tail", + "in": "query", + "description": "Number of lines to return from the end of the logs, or 'all'", + "schema": { + "type": "string", + "default": "all" + } + } + ], + "responses": { + "200": { + "description": "ExApp logs returned", + "content": { + "text/plain": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/deploy-options/{appId}": { + "get": { + "operationId": "ex_apps_page-get-app-deploy-options", + "summary": "Get the deploy options of an ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Deploy options returned", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeployOptions" + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/disable/{appId}": { + "get": { + "operationId": "ex_apps_page-disable-app", + "summary": "Disable an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp disabled", + "content": { + "application/json": { + "schema": {} + } + } + }, + "500": { + "description": "ExApp could not be disabled", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/update/{appId}": { + "get": { + "operationId": "ex_apps_page-update-app", + "summary": "Update an ExApp", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExApp updated", + "content": { + "application/json": { + "schema": {} + } + } + }, + "500": { + "description": "ExApp could not be updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/uninstall/{appId}": { + "get": { + "operationId": "ex_apps_page-uninstall-app", + "summary": "Unregister an ExApp and optionally remove its container and data", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "removeContainer", + "in": "query", + "description": "Whether to remove the ExApp container", + "schema": { + "type": "boolean", + "default": true + } + }, + { + "name": "removeData", + "in": "query", + "description": "Whether to remove the ExApp data volume", + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp uninstalled", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/force": { + "post": { + "operationId": "ex_apps_page-force", + "summary": "Mark an ExApp as compatible with the current Nextcloud version", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "ex_apps_page" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "appId" + ], + "properties": { + "appId": { + "type": "string", + "description": "ID of the ExApp" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Compatibility requirement overwritten", + "content": { + "application/json": { + "schema": {} + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons": { + "get": { + "operationId": "daemon_config-get-all-daemon-configs", + "summary": "Get all registered deploy daemons together with the number of ExApps each one runs", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemons returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemons", + "default_daemon_config" + ], + "properties": { + "daemons": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DaemonConfigWithAppsCount" + } + }, + "default_daemon_config": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "post": { + "operationId": "daemon_config-register-daemon-config", + "summary": "Register a new deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonConfigParams" + ], + "properties": { + "daemonConfigParams": { + "type": "object", + "description": "Daemon configuration parameters", + "additionalProperties": { + "type": "object" + } + }, + "defaultDaemon": { + "type": "boolean", + "default": false, + "description": "Whether to set the new daemon as the default one" + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}": { + "delete": { + "operationId": "daemon_config-unregister-daemon-config", + "summary": "Unregister a deploy daemon and remove the ExApps that run on it", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "put": { + "operationId": "daemon_config-update-daemon-config", + "summary": "Update a registered deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonConfigParams" + ], + "properties": { + "daemonConfigParams": { + "type": "object", + "description": "New daemon configuration parameters", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to update", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Daemon updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success", + "daemonConfig" + ], + "properties": { + "success": { + "type": "boolean" + }, + "daemonConfig": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DaemonConfig" + } + ] + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/check": { + "post": { + "operationId": "daemon_config-verify-daemon-connection", + "summary": "Verify the connection to a registered deploy daemon", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to check", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Connection check result returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/verify_connection": { + "post": { + "operationId": "daemon_config-check-daemon-connection", + "summary": "Check the connection to a deploy daemon from the given parameters", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "daemonParams" + ], + "properties": { + "daemonParams": { + "type": "object", + "description": "Daemon parameters to check", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Connection check result returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/add-registry": { + "post": { + "operationId": "daemon_config-add-daemon-docker-registry", + "summary": "Add a Docker registry mapping to a deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "registryMap" + ], + "properties": { + "registryMap": { + "type": "object", + "description": "Docker registry mapping to add", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Registry added", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DaemonConfig" + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Registry could not be added", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/remove-registry": { + "post": { + "operationId": "daemon_config-remove-daemon-docker-registry", + "summary": "Remove a Docker registry mapping from a deploy daemon", + "description": "This endpoint requires admin access\nThis endpoint requires password confirmation", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "registryMap" + ], + "properties": { + "registryMap": { + "type": "object", + "description": "Docker registry mapping to remove", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Registry removed", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DaemonConfig" + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Registry could not be removed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/test_deploy": { + "post": { + "operationId": "daemon_config-start-test-deploy", + "summary": "Start a test deployment on a deploy daemon", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon to deploy on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy started", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "status" + ], + "properties": { + "status": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "404": { + "description": "Daemon config not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "500": { + "description": "Test deploy could not be started", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "daemon_config-stop-test-deploy", + "summary": "Stop the running test deployment", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon the test runs on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy stopped", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "success" + ], + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/index.php/apps/app_api/daemons/{name}/test_deploy/status": { + "get": { + "operationId": "daemon_config-get-test-deploy-status", + "summary": "Get the status of the running test deployment", + "description": "This endpoint requires admin access", + "tags": [ + "daemon_config" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "path", + "description": "Name of the daemon the test runs on", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Test deploy status returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + }, + "404": { + "description": "Test ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/info/nextcloud_url": { + "get": { + "operationId": "ocs_ex_app-get-nextcloud-url", + "summary": "Get the base URL of this Nextcloud instance", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Base URL returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "base_url" + ], + "properties": { + "base_url": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/{list}": { + "get": { + "operationId": "ocs_ex_app-get-ex-apps-list", + "summary": "Get a list of registered ExApps", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "list", + "in": "path", + "description": "Which ExApps to return", + "required": true, + "schema": { + "type": "string", + "default": "enabled", + "enum": [ + "all", + "enabled" + ] + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApps list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExApp" + } + } + } + } + } + } + } + } + }, + "400": { + "description": "Invalid list type", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/info/{appId}": { + "get": { + "operationId": "ocs_ex_app-get-ex-app", + "summary": "Get information about a registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp info returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExApp" + } + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/request/{appId}": { + "post": { + "operationId": "ocs_ex_app-request-to-ex-app", + "summary": "Proxy a request from one ExApp to another registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "type": "string", + "description": "Route inside the target ExApp to call" + }, + "userId": { + "type": "string", + "nullable": true, + "default": null, + "description": "User to perform the request on behalf of, or null" + }, + "method": { + "type": "string", + "default": "POST", + "description": "HTTP method to use" + }, + "params": { + "type": "object", + "default": {}, + "description": "Request parameters", + "additionalProperties": { + "type": "object" + } + }, + "options": { + "type": "object", + "default": {}, + "description": "Additional request options", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the target ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp response returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExAppRequestResult" + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + }, + "400": { + "description": "Request to the ExApp failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/request/{appId}/{$userId}": { + "post": { + "operationId": "ocs_ex_app-ae-request-to-ex-app", + "summary": "Proxy a request from one ExApp to another registered ExApp (deprecated alias)", + "description": "This endpoint requires admin access", + "deprecated": true, + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "route" + ], + "properties": { + "route": { + "type": "string", + "description": "Route inside the target ExApp to call" + }, + "userId": { + "type": "string", + "nullable": true, + "default": null, + "description": "User to perform the request on behalf of, or null" + }, + "method": { + "type": "string", + "default": "POST", + "description": "HTTP method to use" + }, + "params": { + "type": "object", + "default": {}, + "description": "Request parameters", + "additionalProperties": { + "type": "object" + } + }, + "options": { + "type": "object", + "default": {}, + "description": "Additional request options", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the target ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "$userId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp response returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "anyOf": [ + { + "$ref": "#/components/schemas/ExAppRequestResult" + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + }, + "400": { + "description": "Request to the ExApp failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/{appId}/enabled": { + "put": { + "operationId": "ocs_ex_app-set-ex-app-enabled", + "summary": "Enable or disable a registered ExApp", + "description": "This endpoint requires admin access", + "tags": [ + "ocs_ex_app" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "enabled" + ], + "properties": { + "enabled": { + "type": "integer", + "format": "int64", + "description": "New state: 1 to enable, 0 to disable" + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "ExApp state changed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "ExApp is already in the requested state or the state change failed", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "401": { + "description": "Current user is not logged in", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "403": { + "description": "Logged in account must be an admin", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/log": { + "post": { + "operationId": "ocs_api-log", + "summary": "Log a message to the Nextcloud log on behalf of an ExApp", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "level", + "message" + ], + "properties": { + "level": { + "type": "integer", + "format": "int64", + "description": "Log level (0 - debug, 1 - info, 2 - warning, 3 - error, 4 - fatal)" + }, + "message": { + "type": "string", + "description": "Message to log" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Message logged successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Invalid log level", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/users": { + "get": { + "operationId": "ocs_api-getnc-users-list", + "summary": "Get a list of all Nextcloud user IDs", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Users list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/apps/status/{appId}": { + "put": { + "operationId": "ocs_api-set-app-init-progress-deprecated", + "summary": "Update the initialization progress of an ExApp by its appid", + "deprecated": true, + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "progress" + ], + "properties": { + "progress": { + "type": "integer", + "format": "int64", + "description": "Initialization progress in percent (0-100)" + }, + "error": { + "type": "string", + "default": "", + "description": "Error message in case the initialization failed" + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initialization progress updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/ex-app/status": { + "put": { + "operationId": "ocs_api-set-app-init-progress", + "summary": "Update the initialization progress of the calling ExApp", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "progress" + ], + "properties": { + "progress": { + "type": "integer", + "format": "int64", + "description": "Initialization progress in percent (0-100)" + }, + "error": { + "type": "string", + "default": "", + "description": "Error message in case the initialization failed" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initialization progress updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/ex-app/state": { + "get": { + "operationId": "ocs_api-get-enabled-state", + "summary": "Get the enabled state of the calling ExApp (0 for disabled, 1 for enabled)", + "description": "Note: This endpoint is accessible even if the ExApp itself is disabled.", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Enabled state returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/info/nextcloud_url/absolute": { + "get": { + "operationId": "ocs_api-get-nextcloud-absolute-url", + "summary": "Build an absolute URL from a Nextcloud-relative URL", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "url", + "in": "query", + "description": "Relative URL to convert into an absolute one", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Absolute URL returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "absolute_url" + ], + "properties": { + "absolute_url": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/config": { + "post": { + "operationId": "app_config-set-app-config-value", + "summary": "Set a configuration value for the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKey", + "configValue" + ], + "properties": { + "configKey": { + "type": "string", + "description": "Configuration key" + }, + "configValue": { + "type": "object", + "description": "Configuration value" + }, + "sensitive": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Whether the value is sensitive and should be stored encrypted (1) or not (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Config value set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExAppConfig" + } + } + } + } + } + } + } + }, + "400": { + "description": "Config key is empty or the value could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "app_config-delete-app-config-values", + "summary": "Delete configuration values of the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "configKeys[]", + "in": "query", + "description": "Configuration keys to delete", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Number of deleted config values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "400": { + "description": "Failed to delete the config values", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "No matching config values were found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/config/get-values": { + "post": { + "operationId": "app_config-get-app-config-values", + "summary": "Get configuration values of the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKeys" + ], + "properties": { + "configKeys": { + "type": "array", + "description": "Configuration keys to retrieve", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Config values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExAppConfigValue" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/preference": { + "post": { + "operationId": "preferences-set-user-config-value", + "summary": "Set a preference value for the current user and the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKey", + "configValue" + ], + "properties": { + "configKey": { + "type": "string", + "description": "Preference key" + }, + "configValue": { + "type": "object", + "description": "Preference value" + }, + "sensitive": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Whether the value is sensitive and should be stored encrypted (1) or not (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Preference value set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExAppPreference" + } + } + } + } + } + } + } + }, + "400": { + "description": "Config key is empty or the value could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "preferences-delete-user-config-values", + "summary": "Delete preference values of the current user for the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "configKeys[]", + "in": "query", + "description": "Preference keys to delete", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Number of deleted preference values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "400": { + "description": "Failed to delete the preference values", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "No matching preference values were found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/preference/get-values": { + "post": { + "operationId": "preferences-get-user-config-values", + "summary": "Get preference values of the current user for the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKeys" + ], + "properties": { + "configKeys": { + "type": "array", + "description": "Preference keys to retrieve", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Preference values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExAppConfigValue" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/notification": { + "post": { + "operationId": "notifications-send-notification", + "summary": "Send a notification to a user on behalf of the calling ExApp", + "tags": [ + "notifications" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "params" + ], + "properties": { + "params": { + "type": "object", + "description": "Notification parameters", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "authorization-app-api", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Notification sent", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/occ_command": { + "post": { + "operationId": "occ_command-register-command", + "summary": "Register an occ command for the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "description", + "execute_handler" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the command" + }, + "description": { + "type": "string", + "description": "Description of the command" + }, + "execute_handler": { + "type": "string", + "description": "Handler route called when the command is executed" + }, + "hidden": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Whether the command is hidden from the command list (1) or not (0)" + }, + "arguments": { + "type": "array", + "default": [], + "description": "Command argument definitions", + "items": { + "type": "object" + } + }, + "options": { + "type": "array", + "default": [], + "description": "Command option definitions", + "items": { + "type": "object" + } + }, + "usages": { + "type": "array", + "default": [], + "description": "Example usages of the command", + "items": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Command could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "occ_command-unregister-command", + "summary": "Unregister an occ command of the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the command to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Command not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "occ_command-get-command", + "summary": "Get an occ command of the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the command", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/OccCommand" + } + } + } + } + } + } + } + }, + "404": { + "description": "Command not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/talk_bot": { + "post": { + "operationId": "talk_bot-register-ex-app-talk-bot", + "summary": "Register a Talk bot for the calling ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "route", + "description" + ], + "properties": { + "name": { + "type": "string", + "description": "Bot display name" + }, + "route": { + "type": "string", + "description": "ExApp route that receives bot messages" + }, + "description": { + "type": "string", + "description": "Description of the bot" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Talk bot registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TalkBot" + } + } + } + } + } + } + } + }, + "400": { + "description": "Talk bot could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "talk_bot-unregister-ex-app-talk-bot", + "summary": "Unregister a Talk bot of the calling ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "route", + "in": "query", + "description": "ExApp route of the bot to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Talk bot unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "404": { + "description": "Talk bot could not be unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/talk_proxy/{appId}/{route}": { + "post": { + "operationId": "talk_bot-proxy-talk-message", + "summary": "Proxy a Talk chat message to the bot of a registered ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp owning the bot", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "route", + "in": "path", + "description": "ExApp route that receives the message", + "required": true, + "schema": { + "type": "string", + "pattern": "^.+$" + } + }, + { + "name": "x-nextcloud-talk-random", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "x-nextcloud-talk-signature", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Message proxied to the ExApp bot", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Invalid signature or unknown bot", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "500": { + "description": "The ExApp bot could not be reached", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/files-actions-menu": { + "post": { + "operationId": "ocs_ui-register-file-action-menu", + "summary": "Register a files action menu entry for the calling ExApp", + "deprecated": true, + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName", + "actionHandler" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the action" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "actionHandler": { + "type": "string", + "description": "Handler route called when the action is triggered" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display next to the action" + }, + "mime": { + "type": "string", + "default": "file", + "description": "Mimetype the action applies to" + }, + "permissions": { + "type": "integer", + "format": "int64", + "default": 31, + "description": "Required permissions on the file" + }, + "order": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Ordering of the action in the menu" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "File action menu entry could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-unregister-file-action-menu", + "summary": "Unregister a files action menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the action to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "File action menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-file-action-menu", + "summary": "Get a files action menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the action", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/FileAction" + } + } + } + } + } + } + } + }, + "404": { + "description": "File action menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v2/ui/files-actions-menu": { + "post": { + "operationId": "ocs_ui-register-file-action-menu-v2", + "summary": "Register a files action menu entry (v2) for the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName", + "actionHandler" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the action" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "actionHandler": { + "type": "string", + "description": "Handler route called when the action is triggered" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display next to the action" + }, + "mime": { + "type": "string", + "default": "file", + "description": "Mimetype the action applies to" + }, + "permissions": { + "type": "integer", + "format": "int64", + "default": 31, + "description": "Required permissions on the file" + }, + "order": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Ordering of the action in the menu" + }, + "defaultAction": { + "type": "string", + "default": "", + "description": "Whether this is the default action: one of '', 'default' or 'hidden'" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "File action menu entry could not be registered or defaultAction is invalid", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/top-menu": { + "post": { + "operationId": "ocs_ui-register-ex-app-menu-entry", + "summary": "Register a top menu entry for the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the menu entry" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display for the menu entry" + }, + "adminRequired": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Whether the entry is only visible to admins (1) or to everyone (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Top menu entry could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-unregister-ex-app-menu-entry", + "summary": "Unregister a top menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the menu entry to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Top menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-menu-entry", + "summary": "Get a top menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the menu entry", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TopMenu" + } + } + } + } + } + } + } + }, + "404": { + "description": "Top menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/initial-state": { + "post": { + "operationId": "ocs_ui-set-ex-app-initial-state", + "summary": "Set an initial state for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "key", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the initial state belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "key": { + "type": "string", + "description": "Initial state key" + }, + "value": { + "type": "object", + "description": "Initial state value", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Initial state could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-initial-state", + "summary": "Delete an initial state of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the initial state belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "Initial state key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Initial state not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-initial-state", + "summary": "Get an initial state of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the initial state belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "Initial state key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/InitialState" + } + } + } + } + } + } + } + }, + "404": { + "description": "Initial state not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/script": { + "post": { + "operationId": "ocs_ui-set-ex-app-script", + "summary": "Register a script for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "path" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the script belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "path": { + "type": "string", + "description": "Path to the script file inside the ExApp" + }, + "afterAppId": { + "type": "string", + "default": "", + "description": "Load the script after the script of this app" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Script could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-script", + "summary": "Delete a script of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the script belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the script file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Script not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-script", + "summary": "Get a script of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the script belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the script file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Script" + } + } + } + } + } + } + } + }, + "404": { + "description": "Script not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/style": { + "post": { + "operationId": "ocs_ui-set-ex-app-style", + "summary": "Register a style for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "path" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the style belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "path": { + "type": "string", + "description": "Path to the style file inside the ExApp" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Style could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-style", + "summary": "Delete a style of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the style belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the style file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Style not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-style", + "summary": "Get a style of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the style belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the style file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Style" + } + } + } + } + } + } + } + }, + "404": { + "description": "Style not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/settings": { + "post": { + "operationId": "ocs_settings-register-form", + "summary": "Register a declarative settings form for the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "formScheme" + ], + "properties": { + "formScheme": { + "type": "object", + "description": "Declarative settings form scheme", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Settings form could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_settings-unregister-form", + "summary": "Unregister a declarative settings form of the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "formId", + "in": "query", + "description": "ID of the settings form to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Settings form not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_settings-get-form", + "summary": "Get a declarative settings form of the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "formId", + "in": "query", + "description": "ID of the settings form", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + } + } + }, + "404": { + "description": "Settings form not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ai_provider/task_processing": { + "post": { + "operationId": "task_processing-register-provider", + "summary": "Register a Task Processing provider for the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "provider" + ], + "properties": { + "provider": { + "type": "object", + "description": "Task Processing provider definition", + "additionalProperties": { + "type": "object" + } + }, + "customTaskType": { + "type": "object", + "nullable": true, + "description": "Custom task type definition, or null", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Provider could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "task_processing-unregister-provider", + "summary": "Unregister a Task Processing provider of the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the provider to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "task_processing-get-provider", + "summary": "Get a Task Processing provider of the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the provider", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TaskProcessingProvider" + } + } + } + } + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + } + }, + "tags": [ + { + "name": "ex_apps_page", + "description": "ExApps actions controller similar to default one with project-specific changes and additions" + }, + { + "name": "daemon_config", + "description": "DaemonConfig actions (for UI)" + } + ] +} diff --git a/openapi.json b/openapi.json new file mode 100644 index 000000000..678b8ed5f --- /dev/null +++ b/openapi.json @@ -0,0 +1,5282 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "app_api", + "version": "0.0.1", + "description": "Nextcloud AppAPI", + "license": { + "name": "agpl" + } + }, + "components": { + "securitySchemes": { + "basic_auth": { + "type": "http", + "scheme": "basic" + }, + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "Capabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "loglevel", + "version" + ], + "properties": { + "loglevel": { + "type": "integer", + "format": "int64" + }, + "version": { + "type": "string" + } + } + } + } + }, + "ExAppConfig": { + "type": "object", + "required": [ + "id", + "appid", + "configkey", + "configvalue", + "sensitive" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + }, + "sensitive": { + "type": "integer", + "format": "int64" + } + } + }, + "ExAppConfigValue": { + "type": "object", + "required": [ + "configkey", + "configvalue" + ], + "properties": { + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + } + } + }, + "ExAppPreference": { + "type": "object", + "required": [ + "id", + "user_id", + "appid", + "configkey", + "configvalue", + "sensitive" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "user_id": { + "type": "string" + }, + "appid": { + "type": "string" + }, + "configkey": { + "type": "string" + }, + "configvalue": { + "type": "string" + }, + "sensitive": { + "type": "integer", + "format": "int64" + } + } + }, + "FileAction": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "display_name", + "mime", + "permissions", + "order", + "icon", + "action_handler", + "version", + "default_action" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "mime": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "order": { + "type": "integer", + "format": "int64" + }, + "icon": { + "type": "string" + }, + "action_handler": { + "type": "string" + }, + "version": { + "type": "string" + }, + "default_action": { + "type": "string", + "nullable": true + } + } + }, + "InitialState": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "key", + "value" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "key": { + "type": "string" + }, + "value": { + "type": "object" + } + } + }, + "Notification": { + "type": "object", + "required": [ + "app", + "user", + "datetime", + "object_type", + "object_id", + "subject", + "message", + "link", + "icon" + ], + "properties": { + "app": { + "type": "string" + }, + "user": { + "type": "string" + }, + "datetime": { + "type": "string" + }, + "object_type": { + "type": "string" + }, + "object_id": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "message": { + "type": "string" + }, + "link": { + "type": "string" + }, + "icon": { + "type": "string" + } + } + }, + "OCSMeta": { + "type": "object", + "required": [ + "status", + "statuscode" + ], + "properties": { + "status": { + "type": "string" + }, + "statuscode": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "totalitems": { + "type": "string" + }, + "itemsperpage": { + "type": "string" + } + } + }, + "OccCommand": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "description", + "hidden", + "arguments", + "options", + "usages", + "execute_handler" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "hidden": { + "type": "integer", + "format": "int64" + }, + "arguments": { + "type": "array", + "items": { + "type": "object" + } + }, + "options": { + "type": "array", + "items": { + "type": "object" + } + }, + "usages": { + "type": "array", + "items": { + "type": "object" + } + }, + "execute_handler": { + "type": "string" + } + } + }, + "PublicCapabilities": { + "type": "object", + "required": [ + "app_api" + ], + "properties": { + "app_api": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "version": { + "type": "string" + } + } + } + } + }, + "Script": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "path", + "after_app_id" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "after_app_id": { + "type": "string" + } + } + }, + "Style": { + "type": "object", + "required": [ + "id", + "appid", + "type", + "name", + "path" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + } + }, + "TalkBot": { + "type": "object", + "required": [ + "id", + "secret" + ], + "properties": { + "id": { + "type": "string" + }, + "secret": { + "type": "string" + } + } + }, + "TaskProcessingProvider": { + "type": "object", + "required": [ + "id", + "app_id", + "name", + "display_name", + "task_type", + "provider", + "custom_task_type" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "app_id": { + "type": "string", + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + }, + "display_name": { + "type": "string", + "nullable": true + }, + "task_type": { + "type": "string", + "nullable": true + }, + "provider": { + "type": "string", + "nullable": true + }, + "custom_task_type": { + "type": "string", + "nullable": true + } + } + }, + "TopMenu": { + "type": "object", + "required": [ + "id", + "appid", + "name", + "display_name", + "icon", + "admin_required" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "appid": { + "type": "string" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "admin_required": { + "type": "integer", + "format": "int64" + } + } + } + } + }, + "paths": { + "/ocs/v2.php/apps/app_api/api/v1/log": { + "post": { + "operationId": "ocs_api-log", + "summary": "Log a message to the Nextcloud log on behalf of an ExApp", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "level", + "message" + ], + "properties": { + "level": { + "type": "integer", + "format": "int64", + "description": "Log level (0 - debug, 1 - info, 2 - warning, 3 - error, 4 - fatal)" + }, + "message": { + "type": "string", + "description": "Message to log" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Message logged successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Invalid log level", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/users": { + "get": { + "operationId": "ocs_api-getnc-users-list", + "summary": "Get a list of all Nextcloud user IDs", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Users list returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/apps/status/{appId}": { + "put": { + "operationId": "ocs_api-set-app-init-progress-deprecated", + "summary": "Update the initialization progress of an ExApp by its appid", + "deprecated": true, + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "progress" + ], + "properties": { + "progress": { + "type": "integer", + "format": "int64", + "description": "Initialization progress in percent (0-100)" + }, + "error": { + "type": "string", + "default": "", + "description": "Error message in case the initialization failed" + } + } + } + } + } + }, + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initialization progress updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/ex-app/status": { + "put": { + "operationId": "ocs_api-set-app-init-progress", + "summary": "Update the initialization progress of the calling ExApp", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "progress" + ], + "properties": { + "progress": { + "type": "integer", + "format": "int64", + "description": "Initialization progress in percent (0-100)" + }, + "error": { + "type": "string", + "default": "", + "description": "Error message in case the initialization failed" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initialization progress updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/ex-app/state": { + "get": { + "operationId": "ocs_api-get-enabled-state", + "summary": "Get the enabled state of the calling ExApp (0 for disabled, 1 for enabled)", + "description": "Note: This endpoint is accessible even if the ExApp itself is disabled.", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Enabled state returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "404": { + "description": "ExApp not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/info/nextcloud_url/absolute": { + "get": { + "operationId": "ocs_api-get-nextcloud-absolute-url", + "summary": "Build an absolute URL from a Nextcloud-relative URL", + "tags": [ + "ocs_api" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "url", + "in": "query", + "description": "Relative URL to convert into an absolute one", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Absolute URL returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "absolute_url" + ], + "properties": { + "absolute_url": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/config": { + "post": { + "operationId": "app_config-set-app-config-value", + "summary": "Set a configuration value for the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKey", + "configValue" + ], + "properties": { + "configKey": { + "type": "string", + "description": "Configuration key" + }, + "configValue": { + "type": "object", + "description": "Configuration value" + }, + "sensitive": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Whether the value is sensitive and should be stored encrypted (1) or not (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Config value set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExAppConfig" + } + } + } + } + } + } + } + }, + "400": { + "description": "Config key is empty or the value could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "app_config-delete-app-config-values", + "summary": "Delete configuration values of the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "configKeys[]", + "in": "query", + "description": "Configuration keys to delete", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Number of deleted config values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "400": { + "description": "Failed to delete the config values", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "No matching config values were found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/config/get-values": { + "post": { + "operationId": "app_config-get-app-config-values", + "summary": "Get configuration values of the calling ExApp", + "tags": [ + "app_config" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKeys" + ], + "properties": { + "configKeys": { + "type": "array", + "description": "Configuration keys to retrieve", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Config values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExAppConfigValue" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/preference": { + "post": { + "operationId": "preferences-set-user-config-value", + "summary": "Set a preference value for the current user and the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKey", + "configValue" + ], + "properties": { + "configKey": { + "type": "string", + "description": "Preference key" + }, + "configValue": { + "type": "object", + "description": "Preference value" + }, + "sensitive": { + "type": "integer", + "format": "int64", + "nullable": true, + "default": null, + "description": "Whether the value is sensitive and should be stored encrypted (1) or not (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Preference value set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/ExAppPreference" + } + } + } + } + } + } + } + }, + "400": { + "description": "Config key is empty or the value could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "preferences-delete-user-config-values", + "summary": "Delete preference values of the current user for the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "configKeys[]", + "in": "query", + "description": "Preference keys to delete", + "required": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Number of deleted preference values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "integer", + "format": "int64" + } + } + } + } + } + } + } + }, + "400": { + "description": "Failed to delete the preference values", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "No matching preference values were found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ex-app/preference/get-values": { + "post": { + "operationId": "preferences-get-user-config-values", + "summary": "Get preference values of the current user for the calling ExApp", + "tags": [ + "preferences" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "configKeys" + ], + "properties": { + "configKeys": { + "type": "array", + "description": "Preference keys to retrieve", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Preference values returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExAppConfigValue" + } + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/notification": { + "post": { + "operationId": "notifications-send-notification", + "summary": "Send a notification to a user on behalf of the calling ExApp", + "tags": [ + "notifications" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "params" + ], + "properties": { + "params": { + "type": "object", + "description": "Notification parameters", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "authorization-app-api", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Notification sent", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/occ_command": { + "post": { + "operationId": "occ_command-register-command", + "summary": "Register an occ command for the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "description", + "execute_handler" + ], + "properties": { + "name": { + "type": "string", + "description": "Name of the command" + }, + "description": { + "type": "string", + "description": "Description of the command" + }, + "execute_handler": { + "type": "string", + "description": "Handler route called when the command is executed" + }, + "hidden": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Whether the command is hidden from the command list (1) or not (0)" + }, + "arguments": { + "type": "array", + "default": [], + "description": "Command argument definitions", + "items": { + "type": "object" + } + }, + "options": { + "type": "array", + "default": [], + "description": "Command option definitions", + "items": { + "type": "object" + } + }, + "usages": { + "type": "array", + "default": [], + "description": "Example usages of the command", + "items": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Command could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "occ_command-unregister-command", + "summary": "Unregister an occ command of the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the command to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Command not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "occ_command-get-command", + "summary": "Get an occ command of the calling ExApp", + "tags": [ + "occ_command" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the command", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Command returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/OccCommand" + } + } + } + } + } + } + } + }, + "404": { + "description": "Command not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/talk_bot": { + "post": { + "operationId": "talk_bot-register-ex-app-talk-bot", + "summary": "Register a Talk bot for the calling ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "route", + "description" + ], + "properties": { + "name": { + "type": "string", + "description": "Bot display name" + }, + "route": { + "type": "string", + "description": "ExApp route that receives bot messages" + }, + "description": { + "type": "string", + "description": "Description of the bot" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Talk bot registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TalkBot" + } + } + } + } + } + } + } + }, + "400": { + "description": "Talk bot could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "talk_bot-unregister-ex-app-talk-bot", + "summary": "Unregister a Talk bot of the calling ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "route", + "in": "query", + "description": "ExApp route of the bot to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Talk bot unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "boolean" + } + } + } + } + } + } + } + }, + "404": { + "description": "Talk bot could not be unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/talk_proxy/{appId}/{route}": { + "post": { + "operationId": "talk_bot-proxy-talk-message", + "summary": "Proxy a Talk chat message to the bot of a registered ExApp", + "tags": [ + "talk_bot" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "appId", + "in": "path", + "description": "ID of the ExApp owning the bot", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "route", + "in": "path", + "description": "ExApp route that receives the message", + "required": true, + "schema": { + "type": "string", + "pattern": "^.+$" + } + }, + { + "name": "x-nextcloud-talk-random", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "x-nextcloud-talk-signature", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Message proxied to the ExApp bot", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Invalid signature or unknown bot", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "500": { + "description": "The ExApp bot could not be reached", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/files-actions-menu": { + "post": { + "operationId": "ocs_ui-register-file-action-menu", + "summary": "Register a files action menu entry for the calling ExApp", + "deprecated": true, + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName", + "actionHandler" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the action" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "actionHandler": { + "type": "string", + "description": "Handler route called when the action is triggered" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display next to the action" + }, + "mime": { + "type": "string", + "default": "file", + "description": "Mimetype the action applies to" + }, + "permissions": { + "type": "integer", + "format": "int64", + "default": 31, + "description": "Required permissions on the file" + }, + "order": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Ordering of the action in the menu" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "File action menu entry could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-unregister-file-action-menu", + "summary": "Unregister a files action menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the action to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "File action menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-file-action-menu", + "summary": "Get a files action menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the action", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/FileAction" + } + } + } + } + } + } + } + }, + "404": { + "description": "File action menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v2/ui/files-actions-menu": { + "post": { + "operationId": "ocs_ui-register-file-action-menu-v2", + "summary": "Register a files action menu entry (v2) for the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName", + "actionHandler" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the action" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "actionHandler": { + "type": "string", + "description": "Handler route called when the action is triggered" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display next to the action" + }, + "mime": { + "type": "string", + "default": "file", + "description": "Mimetype the action applies to" + }, + "permissions": { + "type": "integer", + "format": "int64", + "default": 31, + "description": "Required permissions on the file" + }, + "order": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Ordering of the action in the menu" + }, + "defaultAction": { + "type": "string", + "default": "", + "description": "Whether this is the default action: one of '', 'default' or 'hidden'" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "File action menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "File action menu entry could not be registered or defaultAction is invalid", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/top-menu": { + "post": { + "operationId": "ocs_ui-register-ex-app-menu-entry", + "summary": "Register a top menu entry for the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "displayName" + ], + "properties": { + "name": { + "type": "string", + "description": "Unique name of the menu entry" + }, + "displayName": { + "type": "string", + "description": "Human-readable display name" + }, + "icon": { + "type": "string", + "default": "", + "description": "Icon to display for the menu entry" + }, + "adminRequired": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Whether the entry is only visible to admins (1) or to everyone (0)" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Top menu entry could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-unregister-ex-app-menu-entry", + "summary": "Unregister a top menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the menu entry to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Top menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-menu-entry", + "summary": "Get a top menu entry of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the menu entry", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Top menu entry returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TopMenu" + } + } + } + } + } + } + } + }, + "404": { + "description": "Top menu entry not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/initial-state": { + "post": { + "operationId": "ocs_ui-set-ex-app-initial-state", + "summary": "Set an initial state for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "key", + "value" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the initial state belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "key": { + "type": "string", + "description": "Initial state key" + }, + "value": { + "type": "object", + "description": "Initial state value", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Initial state could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-initial-state", + "summary": "Delete an initial state of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the initial state belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "Initial state key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Initial state not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-initial-state", + "summary": "Get an initial state of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the initial state belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "description": "Initial state key", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Initial state returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/InitialState" + } + } + } + } + } + } + } + }, + "404": { + "description": "Initial state not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/script": { + "post": { + "operationId": "ocs_ui-set-ex-app-script", + "summary": "Register a script for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "path" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the script belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "path": { + "type": "string", + "description": "Path to the script file inside the ExApp" + }, + "afterAppId": { + "type": "string", + "default": "", + "description": "Load the script after the script of this app" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Script could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-script", + "summary": "Delete a script of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the script belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the script file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Script not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-script", + "summary": "Get a script of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the script belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the script file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Script returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Script" + } + } + } + } + } + } + } + }, + "404": { + "description": "Script not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/style": { + "post": { + "operationId": "ocs_ui-set-ex-app-style", + "summary": "Register a style for a page of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "type", + "name", + "path" + ], + "properties": { + "type": { + "type": "string", + "description": "Page type the style belongs to" + }, + "name": { + "type": "string", + "description": "Name of the page" + }, + "path": { + "type": "string", + "description": "Path to the style file inside the ExApp" + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Style could not be set", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_ui-delete-ex-app-style", + "summary": "Delete a style of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the style belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the style file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Style not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_ui-get-ex-app-style", + "summary": "Get a style of the calling ExApp", + "tags": [ + "ocs_ui" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "type", + "in": "query", + "description": "Page type the style belongs to", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "description": "Name of the page", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "path", + "in": "query", + "description": "Path to the style file inside the ExApp", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Style returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/Style" + } + } + } + } + } + } + } + }, + "404": { + "description": "Style not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ui/settings": { + "post": { + "operationId": "ocs_settings-register-form", + "summary": "Register a declarative settings form for the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "formScheme" + ], + "properties": { + "formScheme": { + "type": "object", + "description": "Declarative settings form scheme", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Settings form could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "ocs_settings-unregister-form", + "summary": "Unregister a declarative settings form of the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "formId", + "in": "query", + "description": "ID of the settings form to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Settings form not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "ocs_settings-get-form", + "summary": "Get a declarative settings form of the calling ExApp", + "tags": [ + "ocs_settings" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "formId", + "in": "query", + "description": "ID of the settings form", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Settings form returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + } + } + }, + "404": { + "description": "Settings form not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + }, + "/ocs/v2.php/apps/app_api/api/v1/ai_provider/task_processing": { + "post": { + "operationId": "task_processing-register-provider", + "summary": "Register a Task Processing provider for the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "provider" + ], + "properties": { + "provider": { + "type": "object", + "description": "Task Processing provider definition", + "additionalProperties": { + "type": "object" + } + }, + "customTaskType": { + "type": "object", + "nullable": true, + "description": "Custom task type definition, or null", + "additionalProperties": { + "type": "object" + } + } + } + } + } + } + }, + "parameters": [ + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "400": { + "description": "Provider could not be registered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "delete": { + "operationId": "task_processing-unregister-provider", + "summary": "Unregister a Task Processing provider of the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the provider to remove", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider unregistered", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "task_processing-get-provider", + "summary": "Get a Task Processing provider of the calling ExApp", + "tags": [ + "task_processing" + ], + "security": [ + {}, + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Name of the provider", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ex-app-id", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Provider returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "$ref": "#/components/schemas/TaskProcessingProvider" + } + } + } + } + } + } + } + }, + "404": { + "description": "Provider not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": {} + } + } + } + } + } + } + } + } + } + } + }, + "tags": [ + { + "name": "ex_apps_page", + "description": "ExApps actions controller similar to default one with project-specific changes and additions" + }, + { + "name": "daemon_config", + "description": "DaemonConfig actions (for UI)" + } + ] +} diff --git a/tests/php/Controller/AppConfigControllerTest.php b/tests/php/Controller/AppConfigControllerTest.php index dbc20d4c4..e6f4978d1 100644 --- a/tests/php/Controller/AppConfigControllerTest.php +++ b/tests/php/Controller/AppConfigControllerTest.php @@ -40,7 +40,7 @@ protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->service = Server::get(ExAppConfigService::class); $this->controller = new AppConfigController($this->request, $this->service); @@ -59,16 +59,16 @@ private function cleanup(): void { public function testSensitiveFlagPersistsOnSet(): void { $response = $this->controller->setAppConfigValue(self::KEY_SECRET, '123', sensitive: 1); self::assertSame(Http::STATUS_OK, $response->getStatus()); - $entity = $response->getData(); - self::assertSame('123', $entity->getConfigvalue()); - self::assertSame(1, $entity->getSensitive()); + $data = $response->getData(); + self::assertSame('123', $data['configvalue']); + self::assertSame(1, $data['sensitive']); } public function testNonSensitiveDefaultsToZero(): void { $response = $this->controller->setAppConfigValue(self::KEY_PLAIN, 'plain', sensitive: null); self::assertSame(Http::STATUS_OK, $response->getStatus()); // The persisted entity has sensitive=0 when null is passed (no flag set). - self::assertSame(0, $response->getData()->getSensitive()); + self::assertSame(0, $response->getData()['sensitive']); } public function testSensitiveFlagPreservedOnUpdateWithoutFlag(): void { @@ -78,7 +78,7 @@ public function testSensitiveFlagPreservedOnUpdateWithoutFlag(): void { // ExAppConfigService only calls setSensitive() when $sensitive !== null. $response = $this->controller->setAppConfigValue(self::KEY_SECRET, 'updated', sensitive: null); self::assertSame(Http::STATUS_OK, $response->getStatus()); - self::assertSame(1, $response->getData()->getSensitive()); + self::assertSame(1, $response->getData()['sensitive']); } public function testGetReturnsAllKeys(): void { @@ -112,7 +112,7 @@ public function testSensitiveDowngradeClearsFlag(): void { // stays readable as plaintext). This mirrors nc_py_api's appcfg_prefs_ex sensitive test. $this->controller->setAppConfigValue(self::KEY_SECRET, '123', sensitive: 1); $response = $this->controller->setAppConfigValue(self::KEY_SECRET, '123', sensitive: 0); - self::assertSame(0, $response->getData()->getSensitive()); + self::assertSame(0, $response->getData()['sensitive']); $rows = $this->controller->getAppConfigValues([self::KEY_SECRET])->getData(); self::assertSame('123', array_column($rows, 'configvalue', 'configkey')[self::KEY_SECRET]); diff --git a/tests/php/Controller/OCSSettingsControllerTest.php b/tests/php/Controller/OCSSettingsControllerTest.php index e39eb3ca6..b0dfcf94b 100644 --- a/tests/php/Controller/OCSSettingsControllerTest.php +++ b/tests/php/Controller/OCSSettingsControllerTest.php @@ -35,7 +35,7 @@ protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->service = Server::get(SettingsService::class); $this->controller = new OCSSettingsController($this->request, $this->service); diff --git a/tests/php/Controller/OCSUiControllerTest.php b/tests/php/Controller/OCSUiControllerTest.php index 1e6a8cec7..bb156cf5a 100644 --- a/tests/php/Controller/OCSUiControllerTest.php +++ b/tests/php/Controller/OCSUiControllerTest.php @@ -50,7 +50,7 @@ protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->topMenuService = Server::get(TopMenuService::class); diff --git a/tests/php/Controller/OccCommandControllerTest.php b/tests/php/Controller/OccCommandControllerTest.php index 2489d7d5a..72f6e4d33 100644 --- a/tests/php/Controller/OccCommandControllerTest.php +++ b/tests/php/Controller/OccCommandControllerTest.php @@ -43,7 +43,7 @@ protected function setUp(): void { $this->insertFakeExApp(self::TEST_APP_ID, self::TEST_PORT); $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->service = Server::get(ExAppOccService::class); $this->controller = new OccCommandController($this->request, $this->service); @@ -67,9 +67,9 @@ public function testRegisterMinimalGetUnregister(): void { $response = $this->controller->getCommand(self::CMD_NAME); self::assertSame(Http::STATUS_OK, $response->getStatus()); $data = $response->getData(); - self::assertSame(self::CMD_NAME, $data->getName()); + self::assertSame(self::CMD_NAME, $data['name']); // Service strips the leading slash from execute_handler. - self::assertSame('handler', $data->getExecuteHandler()); + self::assertSame('handler', $data['execute_handler']); self::assertSame(Http::STATUS_OK, $this->controller->unregisterCommand(self::CMD_NAME)->getStatus()); self::assertSame(Http::STATUS_NOT_FOUND, $this->controller->getCommand(self::CMD_NAME)->getStatus()); @@ -92,9 +92,9 @@ public function testRegisterFullPayloadPersistsArguments(): void { usages: [], ); $data = $this->controller->getCommand(self::CMD_NAME)->getData(); - self::assertSame('desc', $data->getDescription()); - self::assertSame('some_url2', $data->getExecuteHandler()); - self::assertSame($arguments, $data->getArguments()); + self::assertSame('desc', $data['description']); + self::assertSame('some_url2', $data['execute_handler']); + self::assertSame($arguments, $data['arguments']); } public function testRegisterReplacesExistingCommand(): void { @@ -102,8 +102,8 @@ public function testRegisterReplacesExistingCommand(): void { $this->controller->registerCommand(self::CMD_NAME, 'first desc', 'handler_v1'); $this->controller->registerCommand(self::CMD_NAME, 'updated desc', 'handler_v2'); $data = $this->controller->getCommand(self::CMD_NAME)->getData(); - self::assertSame('updated desc', $data->getDescription()); - self::assertSame('handler_v2', $data->getExecuteHandler()); + self::assertSame('updated desc', $data['description']); + self::assertSame('handler_v2', $data['execute_handler']); } public function testGetMissingReturns404(): void { diff --git a/tests/php/Controller/PreferencesControllerTest.php b/tests/php/Controller/PreferencesControllerTest.php index 1426ad470..0358afb30 100644 --- a/tests/php/Controller/PreferencesControllerTest.php +++ b/tests/php/Controller/PreferencesControllerTest.php @@ -42,7 +42,7 @@ protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $user = $this->createMock(IUser::class); $user->method('getUID')->willReturn(self::TEST_USER_ID); @@ -66,25 +66,25 @@ private function cleanup(): void { public function testSensitiveFlagPersistsOnSet(): void { $response = $this->controller->setUserConfigValue(self::KEY_SECRET, '123', sensitive: 1); self::assertSame(Http::STATUS_OK, $response->getStatus()); - self::assertSame('123', $response->getData()->getConfigvalue()); - self::assertSame(1, $response->getData()->getSensitive()); + self::assertSame('123', $response->getData()['configvalue']); + self::assertSame(1, $response->getData()['sensitive']); } public function testNonSensitiveDefaultsToZero(): void { $response = $this->controller->setUserConfigValue(self::KEY_PLAIN, 'plain', sensitive: null); - self::assertSame(0, $response->getData()->getSensitive()); + self::assertSame(0, $response->getData()['sensitive']); } public function testSensitiveFlagPreservedOnUpdateWithoutFlag(): void { $this->controller->setUserConfigValue(self::KEY_SECRET, 'orig', sensitive: 1); $response = $this->controller->setUserConfigValue(self::KEY_SECRET, 'updated', sensitive: null); - self::assertSame(1, $response->getData()->getSensitive()); + self::assertSame(1, $response->getData()['sensitive']); } public function testSensitiveDowngradeClearsFlag(): void { $this->controller->setUserConfigValue(self::KEY_SECRET, '123', sensitive: 1); $response = $this->controller->setUserConfigValue(self::KEY_SECRET, '123', sensitive: 0); - self::assertSame(0, $response->getData()->getSensitive()); + self::assertSame(0, $response->getData()['sensitive']); $rows = $this->controller->getUserConfigValues([self::KEY_SECRET])->getData(); self::assertSame('123', array_column($rows, 'configvalue', 'configkey')[self::KEY_SECRET]); } diff --git a/tests/php/Controller/TalkBotControllerTest.php b/tests/php/Controller/TalkBotControllerTest.php index a5c1c6700..6fd9d584f 100644 --- a/tests/php/Controller/TalkBotControllerTest.php +++ b/tests/php/Controller/TalkBotControllerTest.php @@ -67,7 +67,7 @@ protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->controller = new TalkBotController( diff --git a/tests/php/Controller/TaskProcessingControllerTest.php b/tests/php/Controller/TaskProcessingControllerTest.php index 81e2e10df..bf5f9d882 100644 --- a/tests/php/Controller/TaskProcessingControllerTest.php +++ b/tests/php/Controller/TaskProcessingControllerTest.php @@ -38,7 +38,7 @@ protected function setUp(): void { parent::setUp(); $this->request = $this->createMock(IRequest::class); $this->request->method('getHeader')->willReturnCallback( - fn (string $name): string => $name === 'EX-APP-ID' ? self::TEST_APP_ID : '' + fn (string $name): string => strtoupper($name) === 'EX-APP-ID' ? self::TEST_APP_ID : '' ); $this->service = Server::get(TaskProcessingService::class); $this->controller = new TaskProcessingController( @@ -79,9 +79,9 @@ public function testRegisterGetUnregister(): void { $response = $this->controller->getProvider(self::PROVIDER_ID); self::assertSame(Http::STATUS_OK, $response->getStatus()); $data = $response->getData(); - self::assertSame(self::PROVIDER_ID, $data->getName()); - self::assertSame('Test Display Name', $data->getDisplayName()); - self::assertSame('core:text2image', $data->getTaskType()); + self::assertSame(self::PROVIDER_ID, $data['name']); + self::assertSame('Test Display Name', $data['display_name']); + self::assertSame('core:text2image', $data['task_type']); $response = $this->controller->unregisterProvider(self::PROVIDER_ID); self::assertSame(Http::STATUS_OK, $response->getStatus()); diff --git a/vendor-bin/openapi-extractor/composer.json b/vendor-bin/openapi-extractor/composer.json new file mode 100644 index 000000000..e7c66aa3c --- /dev/null +++ b/vendor-bin/openapi-extractor/composer.json @@ -0,0 +1,10 @@ +{ + "config": { + "platform": { + "php": "8.2" + } + }, + "require-dev": { + "nextcloud/openapi-extractor": "^1.8.7" + } +} diff --git a/vendor-bin/openapi-extractor/composer.lock b/vendor-bin/openapi-extractor/composer.lock new file mode 100644 index 000000000..65ed78f93 --- /dev/null +++ b/vendor-bin/openapi-extractor/composer.lock @@ -0,0 +1,247 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "a015e4c10d900a2b93cc64dbb63af51c", + "packages": [], + "packages-dev": [ + { + "name": "adhocore/cli", + "version": "v1.9.4", + "source": { + "type": "git", + "url": "https://github.com/adhocore/php-cli.git", + "reference": "474dc3d7ab139796be98b104d891476e3916b6f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/adhocore/php-cli/zipball/474dc3d7ab139796be98b104d891476e3916b6f4", + "reference": "474dc3d7ab139796be98b104d891476e3916b6f4", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ahc\\Cli\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jitendra Adhikari", + "email": "jiten.adhikary@gmail.com" + } + ], + "description": "Command line interface library for PHP", + "keywords": [ + "argument-parser", + "argv-parser", + "cli", + "cli-action", + "cli-app", + "cli-color", + "cli-option", + "cli-writer", + "command", + "console", + "console-app", + "php-cli", + "php8", + "stream-input", + "stream-output" + ], + "support": { + "issues": "https://github.com/adhocore/php-cli/issues", + "source": "https://github.com/adhocore/php-cli/tree/v1.9.4" + }, + "funding": [ + { + "url": "https://paypal.me/ji10", + "type": "custom" + }, + { + "url": "https://github.com/adhocore", + "type": "github" + } + ], + "time": "2025-05-11T13:23:54+00:00" + }, + { + "name": "nextcloud/openapi-extractor", + "version": "v1.8.7", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-releases/openapi-extractor.git", + "reference": "230f61925c362779652b0038a1314ce5f931e853" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-releases/openapi-extractor/zipball/230f61925c362779652b0038a1314ce5f931e853", + "reference": "230f61925c362779652b0038a1314ce5f931e853", + "shasum": "" + }, + "require": { + "adhocore/cli": "^1.7", + "ext-simplexml": "*", + "nikic/php-parser": "^5.0", + "php": "^8.1", + "phpstan/phpdoc-parser": "^2.1" + }, + "require-dev": { + "nextcloud/coding-standard": "^1.4.0", + "nextcloud/ocp": "dev-master", + "rector/rector": "^2.2.8" + }, + "bin": [ + "bin/generate-spec", + "bin/merge-specs" + ], + "type": "library", + "autoload": { + "psr-4": { + "OpenAPIExtractor\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AGPL-3.0-or-later" + ], + "description": "A tool for extracting OpenAPI specifications from Nextcloud source code", + "support": { + "issues": "https://github.com/nextcloud-releases/openapi-extractor/issues", + "source": "https://github.com/nextcloud-releases/openapi-extractor/tree/v1.8.7" + }, + "time": "2025-12-02T09:52:06+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + }, + "time": "2026-01-25T14:56:51+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "platform-overrides": { + "php": "8.2" + }, + "plugin-api-version": "2.9.0" +}