From a64b859e463ac81fd637cf7c31cb9cedaf968915 Mon Sep 17 00:00:00 2001 From: fyears <1142836+fyears@users.noreply.github.com> Date: Sat, 15 Jun 2024 22:54:56 +0800 Subject: [PATCH] add koofr --- .env.example.txt | 2 + .github/workflows/auto-build.yml | 2 + .github/workflows/release.yml | 2 + README.md | 5 + docs/remote_services/koofr/README.md | 38 + esbuild.config.mjs | 4 + package.json | 2 + pro/src/account.ts | 5 + pro/src/baseTypesPro.ts | 24 +- pro/src/fsKoofr.ts | 577 ++ pro/src/koofrApi.d.ts | 9953 ++++++++++++++++++++++++++ pro/src/langs/en.json | 35 + pro/src/langs/zh_cn.json | 40 + pro/src/langs/zh_tw.json | 40 + pro/src/settingsKoofr.ts | 367 + pro/src/settingsPro.ts | 19 +- src/baseTypes.ts | 12 +- src/fsGetter.ts | 3 + src/importExport.ts | 3 + src/main.ts | 85 + src/settings.ts | 25 +- styles.css | 19 + tests/configPersist.test.ts | 3 + webpack.config.js | 4 + 24 files changed, 11263 insertions(+), 6 deletions(-) create mode 100644 docs/remote_services/koofr/README.md create mode 100644 pro/src/fsKoofr.ts create mode 100644 pro/src/koofrApi.d.ts create mode 100644 pro/src/settingsKoofr.ts diff --git a/.env.example.txt b/.env.example.txt index ee851bf..72b2088 100644 --- a/.env.example.txt +++ b/.env.example.txt @@ -11,3 +11,5 @@ PCLOUD_CLIENT_ID= PCLOUD_CLIENT_SECRET= YANDEXDISK_CLIENT_ID= YANDEXDISK_CLIENT_SECRET= +KOOFR_CLIENT_ID= +KOOFR_CLIENT_SECRET= diff --git a/.github/workflows/auto-build.yml b/.github/workflows/auto-build.yml index 82e4bc4..fcb62b1 100644 --- a/.github/workflows/auto-build.yml +++ b/.github/workflows/auto-build.yml @@ -29,6 +29,8 @@ jobs: PCLOUD_CLIENT_SECRET: ${{secrets.PCLOUD_CLIENT_SECRET}} YANDEXDISK_CLIENT_ID: ${{secrets.YANDEXDISK_CLIENT_ID}} YANDEXDISK_CLIENT_SECRET: ${{secrets.YANDEXDISK_CLIENT_SECRET}} + KOOFR_CLIENT_ID: ${{secrets.KOOFR_CLIENT_ID}} + KOOFR_CLIENT_SECRET: ${{secrets.KOOFR_CLIENT_SECRET}} strategy: matrix: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 09080f6..da81c37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,6 +33,8 @@ jobs: PCLOUD_CLIENT_SECRET: ${{secrets.PCLOUD_CLIENT_SECRET}} YANDEXDISK_CLIENT_ID: ${{secrets.YANDEXDISK_CLIENT_ID}} YANDEXDISK_CLIENT_SECRET: ${{secrets.YANDEXDISK_CLIENT_SECRET}} + KOOFR_CLIENT_ID: ${{secrets.KOOFR_CLIENT_ID}} + KOOFR_CLIENT_SECRET: ${{secrets.KOOFR_CLIENT_SECRET}} strategy: matrix: diff --git a/README.md b/README.md index 43d4714..f86e1c1 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ This is yet another unofficial sync plugin for Obsidian. If you like it or find - Box (PRO feature) - pCloud (PRO feature) - Yandex Disk (PRO feature) + - Koofr (PRO feature) - [Here](./docs/services_connectable_or_not.md) shows more connectable (or not-connectable) services in details. - **Obsidian Mobile supported.** Vaults can be synced across mobile and desktop devices with the cloud service as the "broker". - **[End-to-end encryption](./docs/encryption/README.md) supported.** Files would be encrypted using openssl format before being sent to the cloud **if** user specify a password. @@ -142,6 +143,10 @@ PRO (paid) feature "sync with pCloud" allows users to to sync with pCloud (using PRO (paid) feature "sync with Yandex Disk" allows users to to sync with Yandex Disk (using its native API instead of webdav). Tutorials and limitations are documented [here](./docs/remote_services/yandexdisk/README.md). +### Yandex Disk (PRO feature) + +PRO (paid) feature "sync with Koofr" allows users to to sync with Koofr (using its native API instead of webdav). Tutorials and limitations are documented [here](./docs/remote_services/koofr/README.md). + ## Scheduled Auto Sync - You can configure auto syncing every N minutes in settings. diff --git a/docs/remote_services/koofr/README.md b/docs/remote_services/koofr/README.md new file mode 100644 index 0000000..d4abf5b --- /dev/null +++ b/docs/remote_services/koofr/README.md @@ -0,0 +1,38 @@ +# Koofr (PRO) + +# Links + + + +# Intro + +* It's a PRO feature of Remotely Save plugin. +* **This plugin is NOT an official Koofr product, and just uses Koofr's public api.** + +# Steps + +## Steps of Remotely Save subscription + +1. Please sign up and sign in an online account, connect your plugin to your online account firstly. See [the PRO tutorial](../../pro/README.md) firstly. +2. Subscribe to "sync with Koofr" feature online. +3. Go back to your Remotely Save plugin inside Obsidian, click "Check again" button in PRO settings. So that the plugin knows some features are enabled. In this case, sync with Koofr should be detected. + +## Steps of Connecting to your Koofr + +After you enabled the PRO feature in your Remotely Save plugin, you can connect to your Koofr account now. + +1. In Remotely Save settings, change your sync service to Koofr. +2. Click Auth, visit the link, go to Koofr website to start. +3. Follow the instruction on Koofr, and allow Remotely Save to connect. +4. You will be redirected back to Remotely Save plugin. +5. A notice will tell you that you've connected or not. +6. Sync! The plugin will create a vault folder in the root of your Koofr and upload notes into that folder. +7. **Read the caveats below.** + +# The caveats + +* As of June 2024, this feature is in beta stage. **Back up your vault before using this feature.** + +# Why not use webdav? + +The Remotely Save PRO feture "sync with Koofr" is developed using Koofr's native API, instead of webdav interface. It brings benefits such that the last modified time can be preserved. diff --git a/esbuild.config.mjs b/esbuild.config.mjs index 415c64f..1c3c38e 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -29,6 +29,8 @@ const DEFAULT_PCLOUD_CLIENT_SECRET = process.env.PCLOUD_CLIENT_SECRET || ""; const DEFAULT_YANDEXDISK_CLIENT_ID = process.env.YANDEXDISK_CLIENT_ID || ""; const DEFAULT_YANDEXDISK_CLIENT_SECRET = process.env.YANDEXDISK_CLIENT_SECRET || ""; +const DEFAULT_KOOFR_CLIENT_ID = process.env.KOOFR_CLIENT_ID || ""; +const DEFAULT_KOOFR_CLIENT_SECRET = process.env.KOOFR_CLIENT_SECRET || ""; esbuild .context({ @@ -74,6 +76,8 @@ esbuild "process.env.DEFAULT_PCLOUD_CLIENT_SECRET": `"${DEFAULT_PCLOUD_CLIENT_SECRET}"`, "process.env.DEFAULT_YANDEXDISK_CLIENT_ID": `"${DEFAULT_YANDEXDISK_CLIENT_ID}"`, "process.env.DEFAULT_YANDEXDISK_CLIENT_SECRET": `"${DEFAULT_YANDEXDISK_CLIENT_SECRET}"`, + "process.env.DEFAULT_KOOFR_CLIENT_ID": `"${DEFAULT_KOOFR_CLIENT_ID}"`, + "process.env.DEFAULT_KOOFR_CLIENT_SECRET": `"${DEFAULT_KOOFR_CLIENT_SECRET}"`, global: "window", "process.env.NODE_DEBUG": `undefined`, // ugly fix "process.env.DEBUG": `undefined`, // ugly fix diff --git a/package.json b/package.json index ae7664c..fffb469 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "mocha": "^10.4.0", "npm-check-updates": "^16.14.20", "obsidian": "^1.5.7", + "openapi-typescript": "^7.0.0-rc.0", "ts-loader": "^9.5.1", "ts-node": "^10.9.2", "tslib": "^2.6.2", @@ -86,6 +87,7 @@ "mustache": "^4.2.0", "nanoid": "^5.0.7", "node-diff3": "^3.1.2", + "openapi-fetch": "^0.9.7", "p-queue": "^8.0.1", "path-browserify": "^1.0.1", "pcloud-sdk-js": "^2.0.0", diff --git a/pro/src/account.ts b/pro/src/account.ts index bb08a77..c048cce 100644 --- a/pro/src/account.ts +++ b/pro/src/account.ts @@ -285,6 +285,11 @@ export const checkProRunnableAndFixInplace = async ( service: "yandexdisk", name: "Yandex Disk", }, + { + feature: "feature-koofr", + service: "koofr", + name: "Koofr", + }, ]; for (const { feature, service, name } of toChecked) { diff --git a/pro/src/baseTypesPro.ts b/pro/src/baseTypesPro.ts index 4146884..5ad40b2 100644 --- a/pro/src/baseTypesPro.ts +++ b/pro/src/baseTypesPro.ts @@ -11,7 +11,8 @@ export type PRO_FEATURE_TYPE = | "feature-google_drive" | "feature-box" | "feature-pcloud" - | "feature-yandex_disk"; + | "feature-yandex_disk" + | "feature-koofr"; export interface FeatureInfo { featureName: PRO_FEATURE_TYPE; @@ -114,3 +115,24 @@ export interface YandexDiskConfig { scope: string; kind: "yandexdisk"; } + +/////////////////////////////////////////////////////////// +// Koofr +////////////////////////////////////////////////////////// + +export const COMMAND_CALLBACK_KOOFR = "remotely-save-cb-koofr"; +export const KOOFR_CLIENT_ID = process.env.DEFAULT_KOOFR_CLIENT_ID; +export const KOOFR_CLIENT_SECRET = process.env.DEFAULT_KOOFR_CLIENT_SECRET; + +export interface KoofrConfig { + accessToken: string; + accessTokenExpiresInMs: number; + accessTokenExpiresAtTimeMs: number; + refreshToken: string; + remoteBaseDir?: string; + credentialsShouldBeDeletedAtTimeMs?: number; + scope: string; + api: string; + mountID: string; + kind: "koofr"; +} diff --git a/pro/src/fsKoofr.ts b/pro/src/fsKoofr.ts new file mode 100644 index 0000000..fb1e33c --- /dev/null +++ b/pro/src/fsKoofr.ts @@ -0,0 +1,577 @@ +import { nanoid } from "nanoid"; +import createClient, { type Middleware } from "openapi-fetch"; +import { base64 } from "rfc4648"; +import type { Entity } from "../../src/baseTypes"; +import { FakeFs } from "../../src/fsAll"; +import { getParentFolder } from "../../src/misc"; +import { + COMMAND_CALLBACK_KOOFR, + KOOFR_CLIENT_ID, + KOOFR_CLIENT_SECRET, + type KoofrConfig, +} from "./baseTypesPro"; +import type { paths } from "./koofrApi"; +import type { components } from "./koofrApi"; + +type FilesListRecursiveItem = components["schemas"]["FilesListRecursiveItem"]; +type FilesFile = components["schemas"]["FilesFile"]; + +export const DEFAULT_KOOFR_CONFIG: KoofrConfig = { + accessToken: "", + accessTokenExpiresInMs: 0, + accessTokenExpiresAtTimeMs: 0, + refreshToken: "", + remoteBaseDir: "", + credentialsShouldBeDeletedAtTimeMs: 0, + scope: "", + api: "https://app.koofr.net", + mountID: "", + kind: "koofr", +}; + +/** + * https://app.koofr.net/developers + */ +export const generateAuthUrl = (apiAddr: string, hasCallback: boolean) => { + let callback = `urn:ietf:wg:oauth:2.0:oob`; + if (hasCallback) { + callback = `obsidian://${COMMAND_CALLBACK_KOOFR}`; + } + + const params = new URLSearchParams({ + response_type: "code", + client_id: KOOFR_CLIENT_ID ?? "", + redirect_uri: callback, + scope: "public", + state: nanoid(), + }); + + const url = `${apiAddr}/oauth2/auth?${params}`; + return url; +}; + +interface AuthResSucc { + token_type: "Bearer"; + access_token: string; + expires_in: number; + refresh_token: string; + scope: string | undefined; +} + +interface AuthResFail { + error: string; + error_description: string; +} + +/** + * https://app.koofr.net/developers + */ +export const sendAuthReq = async ( + apiAddr: string, + authCode: string, + errorCallBack: any, + hasCallback: boolean +) => { + let callback = `urn:ietf:wg:oauth:2.0:oob`; + if (hasCallback) { + callback = `obsidian://${COMMAND_CALLBACK_KOOFR}`; + } + try { + const k = { + code: authCode, + grant_type: "authorization_code", + client_id: KOOFR_CLIENT_ID ?? "", + client_secret: KOOFR_CLIENT_SECRET ?? "", + redirect_uri: callback, + }; + // console.debug(k); + const resp1 = await fetch(`${apiAddr}/oauth2/token`, { + method: "POST", + body: new URLSearchParams(k), + }); + + if (resp1.status !== 200) { + const resp2: AuthResFail = await resp1.json(); + throw Error(JSON.stringify(resp2)); + } + + const resp2: AuthResSucc = await resp1.json(); + return resp2; + } catch (e) { + console.error(e); + if (errorCallBack !== undefined) { + await errorCallBack(e); + } + } +}; + +export const sendRefreshTokenReq = async ( + apiAddr: string, + refreshToken: string +) => { + console.debug(`refreshing token`); + const x = await fetch(`${apiAddr}/oauth2/token`, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: new URLSearchParams({ + client_id: KOOFR_CLIENT_ID ?? "", + client_secret: KOOFR_CLIENT_SECRET ?? "", + grant_type: "refresh_token", + refresh_token: refreshToken, + }).toString(), + }); + + if (x.status === 200) { + const y: AuthResSucc = await x.json(); + console.debug(`new token obtained`); + return y; + } else { + const y: AuthResFail = await x.json(); + throw Error(`cannot refresh an access token: ${JSON.stringify(y)}`); + } +}; + +export const setConfigBySuccessfullAuthInplace = async ( + config: KoofrConfig, + authRes: AuthResSucc, + saveUpdatedConfigFunc: () => Promise | undefined +) => { + if (authRes.access_token === undefined || authRes.access_token === "") { + throw Error( + `you should not save the setting for ${JSON.stringify(authRes)}` + ); + } + + config.accessToken = authRes.access_token; + config.accessTokenExpiresAtTimeMs = + Date.now() + authRes.expires_in * 1000 - 5 * 60 * 1000; + config.accessTokenExpiresInMs = authRes.expires_in * 1000; + config.refreshToken = authRes.refresh_token || config.refreshToken; + + config.scope = authRes.scope || config.scope; + + // manually set it expired after 60 days; + config.credentialsShouldBeDeletedAtTimeMs = + Date.now() + 1000 * 60 * 60 * 24 * 59; + + await saveUpdatedConfigFunc?.(); + + console.info("finish updating local info of Koofr token"); +}; + +const getNormPathFromBasedir = (x: string, type: "dir" | "file") => { + if (x === "/" || x === "") { + throw Error(`do not know how to deal with path: ${x}`); + } + + if (!x.startsWith("/")) { + throw Error(`path returned by koofr should starts with slash: ${x}`); + } + + if (type === "file") { + return x.slice(1); + } else if (type === "dir") { + return `${x.slice(1)}/`; + } else { + throw Error(`do not know how to deal with path and type: ${x}, ${type}`); + } +}; + +const getKoofrPath = (fileOrFolderPath: string, remoteBaseDir: string) => { + let key = fileOrFolderPath; + if (fileOrFolderPath === "/" || fileOrFolderPath === "") { + // special + key = `/${remoteBaseDir}`; + } else if (fileOrFolderPath.startsWith("/")) { + console.warn( + `why the path ${fileOrFolderPath} starts with '/'? but we just go on.` + ); + key = `/${remoteBaseDir}${fileOrFolderPath}`; + } else { + key = `/${remoteBaseDir}/${fileOrFolderPath}`; + } + if (key.endsWith("/")) { + key = key.slice(0, key.length - 1); + } + return key; +}; + +const fromItemToEntity = (x: FilesListRecursiveItem): Entity => { + if (x.type === "error") { + throw Error(`cannot understand ${JSON.stringify(x)}`); + } + + const key = getNormPathFromBasedir(x.path ?? "/", x.file?.type as any); + + if (x.file?.type === "dir" || x.file?.type === "file") { + return { + key: key, + keyRaw: key, + mtimeCli: x.file.modified, + mtimeSvr: x.file.modified, + size: x.file.size, + sizeRaw: x.file.size, + hash: x.file.hash, + } as Entity; + } else { + throw Error(`cannot understand ${JSON.stringify(x)}`); + } +}; + +const fromFileToEntity = (x: FilesFile, parentPath: string): Entity => { + const key = getNormPathFromBasedir(`${parentPath}/${x.name}`, x.type as any); + if (x.type === "dir" || x.type === "file") { + return { + key: key, + keyRaw: key, + mtimeCli: x.modified, + mtimeSvr: x.modified, + size: x.size, + sizeRaw: x.size, + hash: x.hash, + } as Entity; + } else { + throw Error(`cannot understand ${JSON.stringify(x)}`); + } +}; + +/** + * https://app.koofr.net/developers + * + */ +// const getAuthHeader = (email: string, password: string) => { +// const x = `${email}:${password}`; +// const y = base64.stringify(new TextEncoder().encode(x)); +// const z = `Basic ${y}`; +// return z; +// }; + +// const getAuthMiddleware = (email: string, password: string) => { +// const authMiddleware: Middleware = { +// async onRequest(req) { +// req.headers.set("Authorization", getAuthHeader(email, password)); +// return req; +// }, +// }; +// return authMiddleware; +// }; + +const getAuthMiddleware = ( + koofrConfig: KoofrConfig, + saveUpdatedConfigFunc: any +) => { + const authMiddleware: Middleware = { + async onRequest(req) { + const getAccessToken = async () => { + if (koofrConfig.refreshToken === "") { + throw Error("The user has not manually auth yet."); + } + + const ts = Date.now(); + const comp = koofrConfig.accessTokenExpiresAtTimeMs > ts; + // console.debug(`koofrConfig.accessTokenExpiresAtTimeMs=${koofrConfig.accessTokenExpiresAtTimeMs},ts=${ts},comp=${comp}`) + if (comp) { + return koofrConfig.accessToken; + } + + // refresh + const k = await sendRefreshTokenReq( + koofrConfig.api, + koofrConfig.refreshToken + ); + koofrConfig.accessToken = k.access_token; + koofrConfig.accessTokenExpiresInMs = k.expires_in * 1000; + koofrConfig.accessTokenExpiresAtTimeMs = + ts + k.expires_in * 1000 - 60 * 2 * 1000; + await saveUpdatedConfigFunc(); + console.info("Koofr accessToken updated"); + return koofrConfig.accessToken; + }; + + const access = await getAccessToken(); + req.headers.set("Authorization", `Bearer ${access}`); + return req; + }, + }; + return authMiddleware; +}; + +export class FakeFsKoofr extends FakeFs { + kind: string; + koofrConfig: KoofrConfig; + remoteBaseDir: string; + vaultFolderExists: boolean; + saveUpdatedConfigFunc: () => Promise; + client: ReturnType>; + placeID: string; + + constructor( + koofrConfig: KoofrConfig, + vaultName: string, + saveUpdatedConfigFunc: () => Promise + ) { + super(); + this.kind = "koofr"; + this.koofrConfig = koofrConfig; + this.remoteBaseDir = this.koofrConfig.remoteBaseDir || vaultName || ""; + this.vaultFolderExists = false; + this.saveUpdatedConfigFunc = saveUpdatedConfigFunc; + this.placeID = this.koofrConfig.mountID; + const client = createClient({ baseUrl: this.koofrConfig.api }); + client.use(getAuthMiddleware(this.koofrConfig, saveUpdatedConfigFunc)); + this.client = client; + } + + async _init() { + if (this.koofrConfig.refreshToken === "") { + throw Error(`You have not auth yet!`); + } + + if (this.placeID === undefined || this.placeID === "") { + const { data, error } = await this.client.GET("/api/v2.1/places"); + const primaryPlaceID = data?.places.filter((x) => x.isPrimary)[0].id; + this.placeID = primaryPlaceID ?? ""; + + if (this.placeID === "") { + throw Error(`cannot find primary placeID`); + } + } + + if (this.vaultFolderExists) { + // pass + } else { + const { data, error } = await this.client.GET( + "/api/v2.1/mounts/{mountId}/files/list", + { + params: { + query: { + path: "/", + }, + path: { + mountId: this.placeID, + }, + }, + } + ); + const x = data?.files.filter((x) => x.name === this.remoteBaseDir); + if ((x?.length ?? 0) > 0) { + this.vaultFolderExists = true; + } else { + const { data, error } = await this.client.POST( + "/api/v2.1/mounts/{mountId}/files/folder", + { + params: { + query: { path: "/" }, + path: { mountId: this.placeID }, + }, + body: { + name: this.remoteBaseDir, + }, + } + ); + if (data !== undefined) { + this.vaultFolderExists = true; + } else { + throw Error(JSON.stringify(error)); + } + } + } + } + + async walk(): Promise { + await this._init(); + const { data, error } = await this.client.GET( + "/content/api/v2.1/mounts/{mountId}/files/listrecursive", + { + params: { + query: { path: this.remoteBaseDir }, + path: { mountId: this.placeID }, + }, + parseAs: "text", + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + const items = JSON.parse( + `[${data.trim().split("\n").join(",")}]` + ) as FilesListRecursiveItem[]; + const entities = items.filter((x) => x.path !== "/").map(fromItemToEntity); + return entities; + } + + async walkPartial(): Promise { + await this._init(); + + const { data, error } = await this.client.GET( + "/api/v2.1/mounts/{mountId}/files/list", + { + params: { + query: { path: this.remoteBaseDir }, + path: { mountId: this.placeID }, + }, + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + const entities = data.files.map((x) => fromFileToEntity(x, "")); + // console.debug(entities); + return entities; + } + + async stat(key: string): Promise { + await this._init(); + const { data, error } = await this.client.GET( + "/api/v2.1/mounts/{mountId}/files/info", + { + params: { + query: { path: getKoofrPath(key, this.remoteBaseDir) }, + path: { mountId: this.placeID }, + }, + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + const entity = fromFileToEntity( + data, + getKoofrPath(getParentFolder(key), this.remoteBaseDir) + ); + // console.debug(entity); + return entity; + } + + async mkdir( + key: string, + mtime?: number | undefined, + ctime?: number | undefined + ): Promise { + await this._init(); + + // "abc/efg" -> "abc/" + const parent = getParentFolder(key); + const itself = key.slice(0, -1).split("/").pop()!; + const { data, error } = await this.client.POST( + "/api/v2.1/mounts/{mountId}/files/folder", + { + params: { + query: { path: getKoofrPath(parent, this.remoteBaseDir) }, + path: { mountId: this.placeID }, + }, + body: { + name: itself, + }, + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + return this.stat(key); + } + + async writeFile( + key: string, + content: ArrayBuffer, + mtime: number, + ctime: number + ): Promise { + await this._init(); + const itself = key.split("/").pop()!; + const { data, error } = await this.client.POST( + "/content/api/v2.1/mounts/{mountId}/files/put", + { + params: { + query: { + path: getKoofrPath(getParentFolder(key), this.remoteBaseDir), + filename: itself, + info: true, + overwrite: true, + autorename: false, + modified: mtime, + }, + path: { mountId: this.placeID }, + }, + + body: content as any, + bodySerializer(body) { + return body; + }, + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + const entity = fromFileToEntity( + data, + getKoofrPath(getParentFolder(key), this.remoteBaseDir) + ); + // console.debug(entity); + return entity; + } + + async readFile(key: string): Promise { + await this._init(); + const { data, error } = await this.client.GET( + "/content/api/v2.1/mounts/{mountId}/files/get", + { + params: { + query: { path: getKoofrPath(key, this.remoteBaseDir), force: true }, + path: { mountId: this.placeID }, + }, + parseAs: "arrayBuffer", + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + return data; + } + + async rename(key1: string, key2: string): Promise { + await this._init(); + throw new Error("Method not implemented."); + } + + async rm(key: string): Promise { + await this._init(); + const { data, error } = await this.client.DELETE( + "/api/v2.1/mounts/{mountId}/files/remove", + { + params: { + query: { path: getKoofrPath(key, this.remoteBaseDir), force: true }, + path: { mountId: this.placeID }, + }, + } + ); + if (error !== undefined) { + throw Error(JSON.stringify(error)); + } + } + + async checkConnect(callbackFunc?: any): Promise { + // if we can init, we can connect + try { + await this._init(); + return true; + } catch (err) { + console.debug(err); + callbackFunc?.(err); + return false; + } + } + + async getUserDisplayName(): Promise { + throw new Error("Method not implemented."); + } + + async revokeAuth(): Promise { + throw new Error("Method not implemented."); + } + + allowEmptyFile(): boolean { + return true; + } +} diff --git a/pro/src/koofrApi.d.ts b/pro/src/koofrApi.d.ts new file mode 100644 index 0000000..5dad67e --- /dev/null +++ b/pro/src/koofrApi.d.ts @@ -0,0 +1,9953 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/api/v2.1/applications": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["applicationsList"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/applications/{clientId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["applicationsRevoke"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/basicconfig": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Basic application configuration + * @description Get basic application configuration. + */ + get: operations["basicConfig"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/changelog": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["changelog"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/changelog/opened": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["changelogOpened"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/changelog/seen": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["changelogSeen"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/devices": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["devices"]; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["devicesNew"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/devices/{deviceId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["devicesDetails"]; + /** + * TODO + * @description TODO + */ + put: operations["devicesEdit"]; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["devicesDelete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/devices/{deviceId}/reauth": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["devicesReauth"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/devices/{deviceId}/search": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["devicesEditSearch"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["groups"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["groupsDetails"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}/attributes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["groupsAttributes"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}/branding/logo": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["groupsBrandingLogoRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}/common": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["groupsCommonEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}/users": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["groupsUsersAdd"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/groups/{groupId}/users/{groupUserId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["groupsUsersEdit"]; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["groupsUsersRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["jobs"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/completed": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["jobsRemoveCompleted"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/files/copy": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["jobsFilesCopy"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/files/importlink": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["jobsFilesImportLink"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/files/move": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["jobsFilesMove"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/files/remove": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["jobsFilesRemove"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/files/restoresnapshot": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["jobsFilesRestoreSnapshot"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/{jobId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["jobsDetails"]; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["jobsRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/jobs/{jobId}/abort": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["jobsAbort"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/links": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["linksAll"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List of places and shared folders. + * @deprecated + * @description Deprecated. Use Places or Shared. + */ + get: operations["mounts"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["mountsDetails"]; + /** + * TODO + * @description TODO + */ + put: operations["mountsEdit"]; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["mountsDelete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/bundle": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["bundle"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/comments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["comments"]; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["commentsNew"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/comments/range": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["commentsRange"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/comments/{commentId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["commentsDetails"]; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["commentsDelete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/copy": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["filesCopy"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/create/{template}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["filesCreate"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesGetLink"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/external": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesExternal"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/externalstatus": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesExternalStatus"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/folder": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["filesFolderNew"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/get": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesGet"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/info": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesInfo"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/list": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesList"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/move": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["filesMove"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/remove": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["filesRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/rename": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["filesRename"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/tags/add": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["filesTagsAdd"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/tags/remove": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["filesTagsRemove"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/tags/set": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["filesTagsSet"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/upload": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesUpload"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/versions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["filesVersions"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/versions/change": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Change file version + * @description Replace a file with an older version + */ + post: operations["filesChangeVersion"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/files/versions/recover": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["filesVersionsRecover"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/groups/{mountGroupId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["mountsGroupsAdd"]; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["mountsGroupsRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["links"]; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["linksCreate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["linksDetails"]; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["linksDelete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/counter": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["linksCounter"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/downloadable": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksSetDownloadable"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/message": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksSetMessage"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["linksRemovePassword"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksResetPassword"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/password/set": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksSetPassword"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/qr": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["linksQr"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/urlHash": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksSetUrlHash"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/links/{linkId}/validity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["linksSetValidity"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/reauth": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["mountsReauth"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["receivers"]; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["receiversCreate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["receiversDetails"]; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["receiversDelete"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/alert": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversSetAlert"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/message": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversSetMessage"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["receiversRemovePassword"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/password/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversResetPassword"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/password/set": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversSetPassword"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/qr": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["receiversQr"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/urlHash": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversSetUrlHash"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/receivers/{receiverId}/validity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["receiversSetValidity"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/submounts": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["mountsSubmountsCreate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/users": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * TODO + * @description TODO + */ + post: operations["mountsUsersAdd"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/mounts/{mountId}/users/{mountUserId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["mountsUsersEdit"]; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["mountsUsersRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/places": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["places"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/receivers": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["receiversAll"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/search": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Search files and folders + * @description Search returns search results in the `hits` list. Mounts are normalized and present on the root level to minimize the response size. + */ + get: operations["search"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/shared": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["shared"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/shared/{mountId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["sharedDetails"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/snapshots": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["snapshots"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/trash": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get deleted files + * @description TODO + */ + get: operations["trash"]; + put?: never; + post?: never; + /** + * Empty trash + * @description TODO + */ + delete: operations["trashEmpty"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/trash/undelete": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Undelete files from trash + * @description TODO + */ + post: operations["trashUndelete"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Current user info + * @description Get current user's info. + */ + get: operations["user"]; + /** + * Update current user + * @description Update current user's info. + */ + put: operations["userEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/activity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["activity"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/appconfig": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Application configuration and feature flags for the current user + * @description Most of the configuration is only useful for the official apps. For unauthenticated users `Basic config` should be used. + */ + get: operations["userAppConfig"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/apw": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["appPasswordsList"]; + /** + * TODO + * @description TODO + */ + put: operations["appPasswordsGenerate"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/apw/{apwId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * TODO + * @description TODO + */ + delete: operations["appPasswordsRevoke"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/attributes": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["userAttributes"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/authenticated": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["userAuthenticated"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/bookmarks": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["bookmarks"]; + /** + * TODO + * @description TODO + */ + put: operations["bookmarksEdit"]; + /** + * TODO + * @description TODO + */ + post: operations["bookmarksCreate"]; + /** + * TODO + * @description TODO + */ + delete: operations["bookmarksRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/changeemail": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["userChangeEmail"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/connections": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Connected users and groups + * @description A list of connected users and groups. This can be used for sharing user and group pickers. + */ + get: operations["connections"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/password": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** + * TODO + * @description TODO + */ + put: operations["userChangePassword"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/settings/branding/logo": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * Remove the current user's branding logo. + * @description Remove the current user's branding logo. + */ + delete: operations["brandingLogoRemove"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/settings/language": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get current preferred language + * @description Get current preferred language. `User / App config` endpoint should be used for the current language (preferred, detected or default). + */ + get: operations["settingsLanguage"]; + /** + * Update current preferred language + * @description Set current preferred language. Valid languages can be obtained using `User / App config` endpoint. + */ + put: operations["settingsLanguageEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/settings/notifications": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get notifications settings + * @description Notification settings control whether the user wants to receive an email when new files are shared or a new comment is posted. Device offline setting is deprecated. + */ + get: operations["settingsNotifications"]; + /** + * Update notification settings + * @description Notification settings control whether the user wants to receive an email when new files are shared or a new comment is posted. + */ + put: operations["settingsNotificationsEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/settings/security": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get security settings + * @description Security settings are used to control automatic or mandatory passwords for links. + */ + get: operations["settingsSecurity"]; + /** + * Update security settings + * @description Security settings are used to control automatic or mandatory passwords for links. + */ + put: operations["settingsSecurityEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v2.1/user/settings/seen": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get seen settings + * @description Seen settings are used for saving whether the current user has already seen the web Intro or Desktop app tip. + */ + get: operations["settingsSeen"]; + /** + * Update seen settings + * @description Seen settings are used for saving whether the current user has already seen the web Intro or Desktop app tip. For partial updates non-changed fields should be `null`. + */ + put: operations["settingsSeenEdit"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/files/get": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Download multiple files in a ZIP archive + * @description Download multiple files in a ZIP archive. + */ + post: operations["filesContentFilesGetMulti"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/files/get/{name}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Download multiple files in a ZIP archive + * @description Helper endpoint to include the name of the ZIP archive because web browsers use the last segment of the URL for the downloaded file name. + */ + post: operations["filesContentFilesGetMultiName"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/groups/{groupId}/branding/logo": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get the group's branding logo + * @description Response image can be a JPEG, PNG or GIF. + */ + get: operations["groupsContentGroupsBrandingLogo"]; + put?: never; + /** + * Update the group's branding logo. + * @description The uploaded image must be smaller than 8 MB and will be automatically resized. + */ + post: operations["groupsContentGroupsBrandingLogoUpdate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/mounts/{mountId}/files/get": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Download a file + * @description Download a file. + */ + get: operations["filesContentFilesGet"]; + put?: never; + /** + * Download a folder with filtered files + * @description Download a folder with filtered files. + */ + post: operations["filesContentFilesGetPost"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/mounts/{mountId}/files/get/{name}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Download a file + * @description Helper endpoint to include the name of the file because web browsers use the last segment of the URL for the downloaded file name. + */ + get: operations["filesContentFilesGetName"]; + put?: never; + /** + * Download a folder with filtered files + * @description Helper endpoint to include the name of the file because web browsers use the last segment of the URL for the downloaded file name. + */ + post: operations["filesContentFilesGetNamePost"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/mounts/{mountId}/files/listrecursive": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a recursive stream of files and folders + * @description + * Get a recursive stream of files and folders. + * + * ## Example response + * + * ```json + * > GET /content/api/v2.1/mounts/f13b5804-563d-4aed-b831-ca0246a1cad1/files/listrecursive?path=/path/to/dir HTTP/1.1 + * > + * < HTTP/1.1 200 OK + * < Content-Type: application/x-ndjson; charset=utf-8 + * < Transfer-Encoding: chunked + * < + * {"type":"file","path":"/","file":{"name":"1","type":"dir","modified":1487861241075,"size":0,"contentType":"","tags":{}}} + * {"type":"file","path":"/01ab.jpg","file":{"name":"01ab.jpg","type":"file","modified":1494936799097,"size":36494,"contentType":"image/jpeg","hash":"2eedb741f199ecc19f1ba815d3d9914d","tags":{}}} + * {"type":"file","path":"/10 (1).txt","file":{"name":"10 (1).txt","type":"file","modified":1559913936402,"size":3,"contentType":"text/plain","hash":"31d30eea8d0968d6458e0ad0027c9f80","tags":{}}} + * {"type":"file","path":"/2","file":{"name":"2","type":"dir","modified":1487861247967,"size":0,"contentType":"","tags":{}}} + * {"type":"file","path":"/2/3","file":{"name":"3","type":"dir","modified":1487861253650,"size":0,"contentType":"","tags":{}}} + * ``` + * + * ## Example response for an offline device + * + * ```json + * > GET /content/api/v2.1/mounts/f13b5804-563d-4aed-b831-ca0246a1cad1/files/listrecursive?path=/path/to/dir HTTP/1.1 + * > + * < HTTP/1.1 404 Not Found + * < Content-Length: 115 + * < Content-Type: application/json; charset=utf-8 + * < + * {"error":{"code":"DeviceOffline","message":"Device is offline"},"requestId":"7d17fa00-eea6-40d6-4ea8-4ef1496530ae"} + * ``` + * + * ## External devices + * + * For external cloud devices list recursive only works if the device is + * synchronized. If the device is not synchronized the error code will be `FilesNotSynced`. + * + * ## Errors + * + * If an error occurs when list items have already been sent the response will end + * with an error item: + * + * ```json + * > GET /content/api/v2.1/mounts/f13b5804-563d-4aed-b831-ca0246a1cad1/files/listrecursive?path=/path/to/dir HTTP/1.1 + * > + * < HTTP/1.1 200 OK + * < Content-Type: application/x-ndjson; charset=utf-8 + * < Transfer-Encoding: chunked + * < + * {"type":"file","path":"/","file":{"name":"","type":"dir","modified":1578316978020,"size":0,"contentType":"","tags":{}}} + * {"type":"file","path":"/.bin","file":{"name":".bin","type":"dir","modified":1578316950052,"size":0,"contentType":"","tags":{}}} + * {"type":"file","path":"/.bin/JSONStream","file":{"name":"JSONStream","type":"file","modified":1578316950024,"size":20,"contentType":"application/octet-stream","tags":{}}} + * {"type":"error","error":{"code":"DeviceOffline","message":"Device is offline"}} + * ``` + * + * ## Paths + * + * All paths in items are relative to the specified path. The first item is always + * an file info for the specified path which means that the first item will always + * have path `/`. + * + */ + get: operations["filesContentFilesListRecursive"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/mounts/{mountId}/files/put": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Upload a file + * @description File can be uploaded either using a multi-part form or directly. You can use Chunked transfer encoding if the size of the file is not known in advance (streaming upload). + */ + post: operations["filesContentFilesPut"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/user/profile-picture": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get user's profile picture + * @description Response image can be a JPEG, PNG or GIF. + */ + get: operations["userProfilePictureContentProfilePicture"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/user/profile-picture/update": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Update user's profile picture. + * @description The uploaded image must be smaller than 8 MB and will be automatically resized. + */ + post: operations["userProfilePictureContentProfilePictureUpdate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/user/settings/branding/logo": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get the current user's branding logo + * @description Response image can be a JPEG, PNG or GIF. + */ + get: operations["brandingContentBrandingLogo"]; + put?: never; + /** + * Update the current user's branding logo. + * @description The uploaded image must be smaller than 8 MB and will be automatically resized. + */ + post: operations["brandingContentBrandingLogoUpdate"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/content/api/v2.1/users/{userId}/profile-picture": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get a user's profile picture + * @description Response image can be a JPEG, PNG or GIF. + */ + get: operations["usersProfilePictureContentProfilePicture"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/ip": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["clientIp"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/oauth2/devicecode": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * OAuth 2.0 Device Code Endpoint + * @description OAuth 2.0 endpoint for obtaining device code. + */ + post: operations["oauth2DeviceCode"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/oauth2/token": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * OAuth 2.0 Token Endpoint + * @description This endpoint should not be used called manually. An OAuth 2 library should be used for calls to this endpoint. + */ + post: operations["oauth2Token"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/profile": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * TODO + * @description TODO + */ + get: operations["profile"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + Activity: { + activity: { + [key: string]: unknown; + }[]; + }; + /** @description ApiError represents API errors. Used when an API throws an error, typically with a HTTP error response-code (3xx, 4xx, 5xx). */ + ApiError: { + error: components["schemas"]["ApiErrorDetails"]; + /** + * @description RequestID is the unique ID of the request + * @example 12341234-1234-1234-1234-123412341234 + */ + requestId: string; + }; + /** @description ApiErrorDetails represents API error details */ + ApiErrorDetails: { + /** + * @description Code is the application relevant detail defined in the API or a common list. + * @example NotFound + */ + code: string; + /** @description Extra is extra error info. */ + extra?: { + [key: string]: + | { + [key: string]: unknown; + } + | undefined; + }; + /** + * @description Message is the explanation of the error which can be shown to the client user. + * @example User could not be found + */ + message: string; + }; + /** @description AppConfig represents user application configuration. */ + AppConfig: { + assets: components["schemas"]["ConfigAssets"]; + branding: components["schemas"]["ConfigBranding"]; + changelog: components["schemas"]["ConfigChangelog"]; + chromeExtension: components["schemas"]["ConfigChromeExtension"]; + emailChange: components["schemas"]["ConfigEmailChange"]; + external: components["schemas"]["ConfigExternal"]; + /** + * @description Extra contains extra settings. + * @example { + * "subscription": { + * "hasIndividualAccount": true, + * "isPayingUser": true + * } + * } + */ + extra: string; + featureFlags: components["schemas"]["ConfigFeatureFlags"]; + frontend: components["schemas"]["ConfigFrontend"]; + groups: components["schemas"]["ConfigGroups"]; + localization: components["schemas"]["ConfigLocalization"]; + logout: components["schemas"]["ConfigLogout"]; + mobile: components["schemas"]["ConfigMobile"]; + mobileApps: components["schemas"]["ConfigMobileApps"]; + oauth2: components["schemas"]["ConfigOAuth2"]; + office: components["schemas"]["ConfigOffice"]; + passwordChange: components["schemas"]["ConfigPasswordChange"]; + product: components["schemas"]["ConfigProduct"]; + search: components["schemas"]["ConfigSearch"]; + snapshots: components["schemas"]["ConfigSnapshots"]; + storageDownloader: components["schemas"]["ConfigStorageDownloader"]; + templates: components["schemas"]["ConfigTemplates"]; + trash: components["schemas"]["ConfigTrash"]; + user: components["schemas"]["ConfigUser"]; + viewer: components["schemas"]["ConfigViewer"]; + }; + AppInstance: { + clientId: string; + /** Format: int64 */ + createdAt: number; + id: string; + name: string; + redirectUri?: string; + scopes: string[]; + userAgent?: string; + }; + AppInstances: { + apps: components["schemas"]["AppInstance"][]; + }; + AppPassword: { + /** Format: int64 */ + created: number; + id: string; + /** Format: int64 */ + lastUsed: number; + name: string; + plain?: string; + scopes: string[]; + }; + AppPasswordGenerate: { + name: string; + scopes: string[]; + }; + AppPasswords: { + passwords: components["schemas"]["AppPassword"][]; + }; + /** @description BasicConfig represents basic application configuration. */ + BasicConfig: { + assets: components["schemas"]["ConfigAssets"]; + frontend: components["schemas"]["BasicConfigFrontend"]; + localization: components["schemas"]["ConfigLocalization"]; + mobile: components["schemas"]["ConfigMobile"]; + product: components["schemas"]["ConfigProduct"]; + }; + /** @description BasicConfigFrontend represents frontend settings. */ + BasicConfigFrontend: { + mfa: components["schemas"]["ConfigFrontendMfa"]; + }; + Bookmark: { + mountId: string; + name: string; + path: string; + }; + Bookmarks: { + bookmarks: components["schemas"]["Bookmark"][]; + }; + Bundle: { + file: components["schemas"]["BundleFile"]; + files?: components["schemas"]["BundleFile"][]; + }; + BundleBookmark: { + name: string; + path: string; + }; + BundleFile: { + bookmark?: components["schemas"]["BundleBookmark"]; + contentType: string; + hash?: string; + link?: components["schemas"]["Link"]; + /** Format: int64 */ + modified: number; + mount?: components["schemas"]["Mount"]; + mountPath?: string; + name: string; + receiver?: components["schemas"]["Receiver"]; + /** Format: int64 */ + size: number; + tags: { + [key: string]: string[] | undefined; + }; + type: string; + vaultRepo?: components["schemas"]["BundleVaultRepo"]; + }; + BundleVaultRepo: { + /** Format: int64 */ + added: number; + id: string; + mountId: string; + name: string; + path: string; + }; + Changelog: { + items: components["schemas"]["ChangelogItem"][]; + url: string; + }; + ChangelogItem: { + category?: string; + categoryColor?: string; + id: string; + link: string; + opened: boolean; + /** Format: int64 */ + published: number; + seen: boolean; + summary: string; + title: string; + }; + ChangelogOpened: { + ids: string[]; + }; + ChangelogSeen: { + ids: string[]; + }; + Comment: { + /** Format: int64 */ + added: number; + content: string; + id: string; + user?: components["schemas"]["UserInfo"]; + }; + CommentCreate: { + content: string; + }; + Comments: { + comments: components["schemas"]["Comment"][]; + }; + /** @description ConfigAssets is deprecated. */ + ConfigAssets: { + /** @description Base is deprecated. */ + base: string; + }; + /** @description ConfigBranding represents branding settings. */ + ConfigBranding: { + user: components["schemas"]["ConfigBrandingUser"]; + }; + /** @description ConfigBrandingUser represents user branding settings. */ + ConfigBrandingUser: { + /** + * @description Enabled defines whether user can change branding settings. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigChangelog represents feature flags settings. */ + ConfigChangelog: { + /** @description Enabled defines whether changelog is enabled. */ + enabled: boolean; + }; + /** @description ConfigMobileApps represents Chrome extension settings. */ + ConfigChromeExtension: { + /** + * @description Id is the Chrome extension ID. + * @example cgigbdaddgndbofikanbfmkpfoonlbpp + */ + id: string; + /** + * @description Offer defines whether Chrome extension banner should be displayed. + * @example true + */ + offer: boolean; + }; + /** @description ConfigPasswordChange represents email change settings. */ + ConfigEmailChange: { + /** + * @description Enable defines whether user can change their email. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigExternal represents external cloud integration settings. */ + ConfigExternal: { + cloudDrive: components["schemas"]["ConfigExternalCloudDrive"]; + dropbox: components["schemas"]["ConfigExternalDropbox"]; + googleDrive: components["schemas"]["ConfigExternalGoogleDrive"]; + oneDrive: components["schemas"]["ConfigExternalOneDrive"]; + }; + /** @description ConfigExternalCloudDrive is deprecated. */ + ConfigExternalCloudDrive: { + /** @description ConnectUrl is deprecated. */ + connectUrl: string; + /** @description Enabled is deprecated. */ + enabled: boolean; + }; + /** @description ConfigExternalDropbox represents Dropbox integration settings. */ + ConfigExternalDropbox: { + /** + * @description ConnectUrl is the URL for connecting new Dropbox places. + * @example /places/dropbox/connect + */ + connectUrl: string; + /** + * @description Enabled defines whether Dropbox integration is enabled. + * @example true + */ + enabled: boolean; + /** + * @description ConnectUrl is the URL for Dropbox user logout. + * @example https://www.dropbox.com/logout + */ + logoutUrl: string; + }; + /** @description ConfigExternalGoogleDrive represents Google Drive integration settings. */ + ConfigExternalGoogleDrive: { + /** + * @description ConnectUrl is the URL for connecting new Google Drive places. + * @example /places/googledrive/connect + */ + connectUrl: string; + /** + * @description Enabled defines whether Google Drive integration is enabled. + * @example true + */ + enabled: boolean; + /** + * @description ConnectUrl is the URL for Google Drive user logout. + * @example https://accounts.google.com/Logout + */ + logoutUrl: string; + }; + /** @description ConfigExternalOneDrive represents OneDrive integration settings. */ + ConfigExternalOneDrive: { + /** + * @description ConnectUrl is the URL for connecting new OneDrive places. + * @example /places/onedrive/connect + */ + connectUrl: string; + /** + * @description Enabled defines whether OneDrive integration is enabled. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigFeatureFlags represents feature flags settings. */ + ConfigFeatureFlags: { + /** @description FeatureFlags contains custom feature flags. */ + featureFlags: { + [key: string]: boolean | undefined; + }; + }; + /** @description ConfigFrontend represents frontend settings. */ + ConfigFrontend: { + activity: components["schemas"]["ConfigFrontendActivity"]; + links: components["schemas"]["ConfigFrontendLinks"]; + mfa: components["schemas"]["ConfigFrontendMfa"]; + navigation: components["schemas"]["ConfigFrontendNavigation"]; + settings: components["schemas"]["ConfigFrontendSettings"]; + upgrade: components["schemas"]["ConfigFrontendUpgrade"]; + }; + /** @description ConfigFrontendActivity is deprecated. */ + ConfigFrontendActivity: { + /** @description Pagination is deprecated. */ + pagination: boolean; + }; + /** @description ConfigFrontendLinks represents links settings. */ + ConfigFrontendLinks: { + /** + * @description CanChangePassword defines whether link passwords can be changed. + * @example true + */ + canChangePassword: boolean; + /** + * @description CanChangeShortUrl defines whether short URLs can be changed. + * @example true + */ + canChangeShortUrl: boolean; + /** + * @description MessageEditEnabled defines whether current user is allowed to set a custom + * link message. + * @example true + */ + messageEditAllowed: boolean; + /** + * @description MessageEditEnabled defines whether custom link message feature is enabled. + * @example true + */ + messageEditEnabled: boolean; + /** + * @description SocialEnabled defines whether social media buttons are displayed. + * @example true + */ + socialEnabled: boolean; + }; + /** @description ConfigFrontendMfa represents Two-factor authentication settings. */ + ConfigFrontendMfa: { + /** + * @description Enabled defines whether Two-factor authentication settings are enabled. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigFrontendNavigation represents navigation settings. */ + ConfigFrontendNavigation: { + androidMedia: components["schemas"]["ConfigFrontendNavigationAndroidMedia"]; + iosMedia: components["schemas"]["ConfigFrontendNavigationIosMedia"]; + wpMedia: components["schemas"]["ConfigFrontendNavigationWpMedia"]; + }; + /** @description ConfigFrontendNavigationAndroidMedia represents Android media settings. */ + ConfigFrontendNavigationAndroidMedia: { + /** + * @description Name is the name of iOS media folder. + * @example My Android Media + */ + name: string; + }; + /** @description ConfigFrontendNavigationIosMedia represents iOS media settings. */ + ConfigFrontendNavigationIosMedia: { + /** + * @description Name is the name of iOS media folder. + * @example My iOS Media + */ + name: string; + }; + /** @description ConfigFrontendNavigationWpMedia is deprecated. */ + ConfigFrontendNavigationWpMedia: { + /** @description Name is deprecated. */ + name: string; + }; + /** @description ConfigFrontendSettings represents frontend settings. */ + ConfigFrontendSettings: { + security: components["schemas"]["ConfigFrontendSettingsSecurity"]; + }; + /** @description ConfigFrontendSettingsSecurity represents frontend security settings. */ + ConfigFrontendSettingsSecurity: { + /** + * @description Enabled defines whether security page is enabled. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigFrontendUpgrade represents upgrade settings. */ + ConfigFrontendUpgrade: { + /** @description Url is the URL of the account/upgrade settings. */ + url: string; + }; + /** @description ConfigGroups represents group settings. */ + ConfigGroups: { + /** @description AddUserUrl contains a custom URL for adding users. */ + addUserUrl?: string; + /** @description BuyResourcesUrl contains a custom URL for buying more resources. */ + buyResourcesUrl?: string; + /** + * @description CanChangeSpace defines whether space can be assigned/modified for group users. + * @example true + */ + canChangeSpace: boolean; + /** + * @description CanChangeUsers defines whether group users can be modified. + * @example true + */ + canChangeUsers: boolean; + /** + * @description Enabled defines whether groups are enabled. + * @example false + */ + enabled: boolean; + }; + /** @description ConfigLocalization represents localization settings. */ + ConfigLocalization: { + /** + * @description HelpLanguage is the language for the help pages. + * @example en + */ + helpLanguage: string; + /** + * @description Language is the current language code. If user did not set a preferred + * language, Accept-Language HTTP header is used for default language + * detection. + * @example en + */ + language: string; + /** @description Languages is a list of languages for the web application. */ + languages: components["schemas"]["ConfigLocalizationLanguage"][]; + }; + /** @description ConfigLocalizationLanguage represents a web application language. */ + ConfigLocalizationLanguage: { + /** + * @description Language is a short code for the language. + * @example en + */ + language: string; + /** + * @description Name is the full name of the language. + * @example English + */ + name: string; + }; + /** @description ConfigLogout represents logout settings. */ + ConfigLogout: { + /** + * @description Url is the URL for logout. + * @example /logout + */ + url: string; + }; + /** @description ConfigMobile represents mobile settings. */ + ConfigMobile: { + /** + * @description IsMobile defines whether user is using a mobile device. It is detected from + * User-Agent header. + * @example false + */ + isMobile: boolean; + }; + /** @description ConfigMobileApps represents mobile apps settings. */ + ConfigMobileApps: { + android: components["schemas"]["ConfigMobileAppsAndroid"]; + ios: components["schemas"]["ConfigMobileAppsIos"]; + wp: components["schemas"]["ConfigMobileAppsWp"]; + }; + /** @description ConfigMobileAppsAndroid represents Android app settings. */ + ConfigMobileAppsAndroid: { + /** + * @description AppGalleryUrl is the URL of HUAWEI AppGallery. + * @example https://appgallery.huawei.com/#/app/C102050115 + */ + appGalleryUrl?: string; + /** + * @description Url is the URL of Google Play store. + * @example https://play.google.com/store/apps/details?id=net.koofr.app + */ + url: string; + }; + /** @description ConfigMobileAppsIos represents iOS app settings. */ + ConfigMobileAppsIos: { + /** + * @description Url is the URL of Apple App store. + * @example https://itunes.apple.com/tr/app/koofr/id714802401 + */ + url: string; + }; + /** @description ConfigMobileAppsWp is deprecated. */ + ConfigMobileAppsWp: { + /** @description Url is deprecated. */ + url: string; + }; + /** @description ConfigOAuth2 is deprecated. */ + ConfigOAuth2: { + /** + * @description Enabled is deprecated. + * @example true + */ + enabled: boolean; + /** + * @description Visible is deprecated. + * @example true + */ + visible: boolean; + }; + /** @description ConfigOffice represents Office integration settings. */ + ConfigOffice: { + /** + * @description Enabled defines whether Office Web Apps integration is enabled. + * @example false + */ + enabled: boolean; + /** + * @description Extensions is a list of file extensions for which Office integration is + * supported. + * @example [ + * "csv", + * "docx", + * "xlsx" + * ] + */ + extensions: string[]; + /** + * @description OfficeOnlineEnabled defines whether Office Online integration is allowed + * for the current user. + * @example true + */ + officeOnlineAllowed: boolean; + /** + * @description OfficeOnlineLocale is the default locale of the Office Online data (e.g. + * Excel numbers and dates locale). + * @example en-US + */ + officeOnlineDataLocale?: string; + /** + * @description OfficeOnlineEnabled defines whether Office Online integration is enabled. + * @example true + */ + officeOnlineEnabled: boolean; + /** + * @description OfficeOnlineLocale is the locale of the Office Online web interface. + * @example en-US + */ + officeOnlineLocale?: string; + }; + /** @description ConfigPasswordChange represents password change settings. */ + ConfigPasswordChange: { + /** + * @description Enable defines whether user can change their password. + * @example true + */ + enabled: boolean; + }; + /** @description ConfigProduct represents product info. */ + ConfigProduct: { + /** + * @description MarketingURL is the URL of the page that contains more info about the + * product. It is used for intro modal in the web application and in the link + * page footer. + * @example https://koofr.eu + */ + marketingUrl: string; + /** + * @description Name is the produt name. + * @example Koofr + */ + name: string; + /** + * @description NameVisible defines whether product name should be visible on auth pages. + * @example false + */ + nameVisible: boolean; + /** + * @description PublicUrl is the public URL of the service. + * @example https://app.koofr.net + */ + publicUrl: string; + }; + /** @description ConfigSearch is deprecated. */ + ConfigSearch: { + /** + * @description Enabled is deprecated. + * @example true + */ + enabled: boolean; + /** + * @description Visible is deprecated. + * @example true + */ + visible: boolean; + }; + /** @description ConfigSnapshots represents snapshots settings. */ + ConfigSnapshots: { + /** + * @description Enabled defines whether snapshots are enabled. + * @example false + */ + enabled: boolean; + }; + /** @description ConfigStorageDownloader is deprecated. */ + ConfigStorageDownloader: { + /** @description Public is deprecated. */ + public: string; + }; + /** @description ConfigTemplates represents empty documents templates settings. */ + ConfigTemplates: { + /** + * @description Enabled defines whether empty documents templates are enabled. + * @example true + */ + enabled: boolean; + /** + * @description Templates is a list of empty documents templates. + * @example [ + * "docx", + * "xlsx", + * "pptx" + * ] + */ + templates: string[]; + }; + /** @description ConfigTrash represents trash settings. */ + ConfigTrash: { + /** @description EmptyEnabled defines whether trash can be emptied. */ + emptyEnabled: boolean; + }; + /** @description ConfigUser represents the current user info. */ + ConfigUser: { + /** + * @description Email is the user's email address. + * @example john@example.com + */ + email: string; + /** + * @description FirstName is the user's first name. Can be empty. + * @example John + */ + firstName: string; + /** + * @description HasPassword defines if user's password is set. User can be without a + * password if they signed in with Google. + * @example true + */ + hasPassword: boolean; + /** + * @description Id is the user's unique ID. + * @example 12341234-1234-1234-1234-123412341234 + */ + id: string; + /** + * @description LastName is the user's last name. Can be empty. + * @example Suitcase + */ + lastName: string; + /** + * Format: int32 + * @description Level is user's level. + * @example 1000 + */ + level: number; + /** @description PhoneNumber is the user's phone number. It is defined in special cases. */ + phoneNumber?: string; + }; + /** @description ConfigViewer represents document viewer settings. */ + ConfigViewer: { + /** + * @description Enabled defines whether document viewer is enabled. + * @example true + */ + enabled: boolean; + }; + Connections: { + groups: components["schemas"]["ConnectionsGroup"][]; + users: components["schemas"]["ConnectionsUser"][]; + }; + ConnectionsGroup: { + id: string; + name: string; + }; + ConnectionsUser: { + email: string; + id: string; + name: string; + }; + Device: { + apiKey: string; + canEdit: boolean; + canRemove: boolean; + id: string; + name: string; + provider: components["schemas"]["DeviceProvider"]; + rootMountId?: string; + searchEnabled: boolean; + /** Format: int64 */ + spaceFree: number; + /** Format: int64 */ + spaceTotal: number; + /** Format: int64 */ + spaceUsed: number; + status: string; + /** Format: int32 */ + version: number; + }; + DeviceCreate: { + name: string; + }; + DeviceProvider: { + data: { + [key: string]: string | undefined; + }; + name: string; + }; + DeviceSearch: { + enabled: boolean; + }; + Devices: { + devices: components["schemas"]["Device"][]; + }; + Files: { + files: components["schemas"]["FilesFile"][]; + }; + FilesCopy: { + ifHash?: string; + /** Format: int64 */ + ifModified?: number; + /** Format: int64 */ + ifSize?: number; + /** Format: int64 */ + modified?: number; + toMountId: string; + toPath: string; + }; + FilesCopyResult: { + name: string; + }; + FilesCreateResult: { + name: string; + }; + FilesExternalStatus: { + status: string; + }; + FilesFile: { + contentType: string; + hash?: string; + /** Format: int64 */ + modified: number; + name: string; + /** Format: int64 */ + size: number; + tags: { + [key: string]: string[] | undefined; + }; + type: string; + }; + FilesFolderCreate: { + name: string; + }; + FilesGetLink: { + link: string; + }; + /** + * @description FilesListRecursiveItem represents recursive file list item. + * @example { + * "file": { + * "contentType": "text/plain", + * "hash": "2eedb741f199ecc19f1ba815d3d9914d", + * "modified": 1494936799097, + * "name": "file.txt", + * "size": 36494, + * "tags": {}, + * "type": "file" + * }, + * "path": "/path/to/file.txt", + * "type": "file" + * } + */ + FilesListRecursiveItem: { + error?: components["schemas"]["ApiErrorDetails"]; + file?: components["schemas"]["FilesFile"]; + /** + * @description Path of the file. + * @example /path/to/file.txt + */ + path?: string; + /** + * @description Type is the type of the item. + * @example file + * @enum {string} + */ + type: "file" | "error"; + }; + FilesMove: { + ifHash?: string; + /** Format: int64 */ + ifModified?: number; + /** Format: int64 */ + ifSize?: number; + toMountId: string; + toPath: string; + }; + FilesMoveResult: { + name: string; + }; + FilesRemove: { + version?: string; + }; + FilesRename: { + name: string; + }; + FilesTagsAdd: { + tags: { + [key: string]: string[] | undefined; + }; + }; + FilesTagsRemove: { + tags: { + [key: string]: string[] | undefined; + }; + }; + FilesTagsSet: { + ifHash?: string; + /** Format: int64 */ + ifModified?: number; + ifOldTags?: { + [key: string]: string[] | undefined; + }; + /** Format: int64 */ + ifSize?: number; + tags: { + [key: string]: string[] | undefined; + }; + }; + FilesUploadLink: { + link: string; + }; + FilesVersion: { + contentType: string; + id: string; + /** Format: int64 */ + modified: number; + /** Format: int64 */ + size: number; + tags: { + [key: string]: string[] | undefined; + }; + type: string; + }; + FilesVersions: { + versions: components["schemas"]["FilesVersion"][]; + }; + FilesVersionsRecover: { + newPath: string; + }; + Group: { + account?: components["schemas"]["GroupAccount"]; + branding: components["schemas"]["GroupBranding"]; + common?: components["schemas"]["GroupCommon"]; + id: string; + name: string; + permissions: { + [key: string]: boolean | undefined; + }; + users: components["schemas"]["GroupUser"][]; + }; + GroupAccount: { + /** Format: int64 */ + capacityMax: number; + /** Format: int64 */ + usersMax?: number; + }; + GroupBranding: { + backgroundColor?: string; + foregroundColor?: string; + logo?: string; + }; + GroupCommon: { + /** Format: int64 */ + spaceTotal: number; + /** Format: int64 */ + spaceUsed: number; + }; + GroupCommonUpdate: { + /** Format: int64 */ + spaceTotal: number; + }; + GroupUser: { + email: string; + firstName: string; + id: string; + lastName: string; + permissions: { + [key: string]: boolean | undefined; + }; + phoneNumber?: string; + /** Format: int64 */ + spaceTotal?: number; + /** Format: int64 */ + spaceUsed?: number; + }; + GroupUserCreate: { + email: string; + permissions?: { + [key: string]: boolean | undefined; + }; + /** Format: int64 */ + spaceTotal?: number; + }; + GroupUserEdit: { + permissions?: { + [key: string]: boolean | undefined; + }; + /** Format: int64 */ + spaceTotal?: number; + }; + Groups: { + groups: components["schemas"]["Group"][]; + }; + Job: { + /** Format: int64 */ + aborted?: number; + /** Format: int64 */ + created: number; + id: string; + parameters: string; + /** Format: int32 */ + progress: number; + result: string; + state: string; + type: string; + }; + JobCopy: { + /** + * @description ConflictResolution defines how the conflicts are resolved. + * @enum {string} + */ + conflictResolution?: "RENAME" | "SKIP"; + files: components["schemas"]["JobMountPathPair"][]; + }; + JobFileDestError: { + error: components["schemas"]["ApiErrorDetails"]; + file: components["schemas"]["JobMountPathPair"]; + }; + JobFileDestErrors: { + errors: components["schemas"]["JobFileDestError"][]; + }; + JobMountPath: { + mountId: string; + path: string; + }; + JobMountPathPair: { + dst: components["schemas"]["JobMountPath"]; + src: components["schemas"]["JobMountPath"]; + }; + JobRemove: { + files: components["schemas"]["JobMountPath"][]; + }; + JobUndelete: { + files: components["schemas"]["JobMountPath"][]; + }; + Jobs: { + jobs: components["schemas"]["Job"][]; + }; + Link: { + /** Format: int64 */ + counter: number; + downloadable: boolean; + hasPassword: boolean; + hash: string; + host: string; + id: string; + message?: string; + mountId: string; + name: string; + password?: string; + passwordRequired: boolean; + passwordRequiredReason?: string; + path: string; + shortUrl: string; + url: string; + /** Format: int64 */ + validFrom?: number; + /** Format: int64 */ + validTo?: number; + }; + LinkCounter: { + /** Format: int64 */ + counter: number; + }; + LinkCreate: { + path: string; + }; + LinkMessage: { + message: string; + }; + LinkSetDownloadable: { + downloadable: boolean; + }; + LinkSetHash: { + hash: string; + }; + LinkSetPassword: { + password: string; + }; + LinkValidity: { + /** Format: int64 */ + validFrom?: number; + /** Format: int64 */ + validTo?: number; + }; + Links: { + links: components["schemas"]["Link"][]; + }; + LinksBundle: { + links: components["schemas"]["Link"][]; + mounts: { + [key: string]: components["schemas"]["Mount"] | undefined; + }; + }; + Mount: { + almostOverQuota: boolean; + canUpload: boolean; + canWrite: boolean; + capabilities: components["schemas"]["MountCapabilities"]; + deviceId?: string; + groups: components["schemas"]["MountGroup"][]; + id: string; + isDir: boolean; + isPrimary: boolean; + isShared: boolean; + name: string; + online: boolean; + origin: string; + overQuota: boolean; + owner: components["schemas"]["MountMember"]; + permissions: { + [key: string]: boolean | undefined; + }; + root?: components["schemas"]["MountRoot"]; + /** Format: int64 */ + spaceTotal?: number; + /** Format: int64 */ + spaceUsed?: number; + type: string; + /** Format: int64 */ + userAdded: number; + users: components["schemas"]["MountUser"][]; + /** Format: int32 */ + version: number; + }; + MountCandidate: { + email: string; + groupId: string; + groupName: string; + id: string; + name: string; + }; + MountCapabilities: { + externalLinks: boolean; + externalStatus: boolean; + officeOnline: boolean; + rawThumbnails: boolean; + tags: boolean; + }; + MountCreate: { + path: string; + }; + MountEdit: { + name: string; + }; + MountGroup: { + /** Format: int64 */ + added: number; + id: string; + name: string; + permissions: { + [key: string]: boolean | undefined; + }; + }; + MountGroupCreate: { + permissions: { + [key: string]: boolean | undefined; + }; + }; + MountMember: { + /** Format: int64 */ + added: number; + email?: string; + id: string; + isGroup: boolean; + name: string; + permissions: { + [key: string]: boolean | undefined; + }; + }; + MountRoot: { + id: string; + name: string; + path: string; + }; + MountSnapshots: { + mountId: string; + mountName: string; + /** Format: int64 */ + mountSpaceTotal: number; + snapshots: components["schemas"]["Snapshot"][]; + }; + MountUser: { + /** Format: int64 */ + added: number; + email: string; + id: string; + name: string; + permissions: { + [key: string]: boolean | undefined; + }; + }; + MountUserCreate: { + email?: string; + id?: string; + permissions: { + [key: string]: boolean | undefined; + }; + }; + MountUserEdit: { + permissions: { + [key: string]: boolean | undefined; + }; + }; + Mounts: { + mounts: components["schemas"]["Mount"][]; + }; + MountsSnapshots: { + mounts: components["schemas"]["MountSnapshots"][]; + }; + Places: { + places: components["schemas"]["Mount"][]; + }; + Profile: { + base: string; + name: string; + /** Format: int32 */ + version: number; + }; + Receiver: { + alert: boolean; + /** Format: int64 */ + counter: number; + hasPassword: boolean; + hash: string; + host: string; + id: string; + mailUploadAddress?: string; + message?: string; + mountId: string; + name: string; + password?: string; + passwordRequiredReason?: string; + path: string; + shortUrl: string; + url: string; + /** Format: int64 */ + validFrom?: number; + /** Format: int64 */ + validTo?: number; + }; + ReceiverCreate: { + path: string; + }; + ReceiverMessage: { + message: string; + }; + ReceiverSetAlert: { + alert: boolean; + }; + ReceiverSetHash: { + hash: string; + }; + ReceiverSetPassword: { + password: string; + }; + ReceiverValidity: { + /** Format: int64 */ + validFrom?: number; + /** Format: int64 */ + validTo?: number; + }; + Receivers: { + receivers: components["schemas"]["Receiver"][]; + }; + ReceiversBundle: { + mounts: { + [key: string]: components["schemas"]["Mount"] | undefined; + }; + receivers: components["schemas"]["Receiver"][]; + }; + SearchHit: { + contentType: string; + link?: components["schemas"]["Link"]; + /** Format: int64 */ + modified: number; + mount?: components["schemas"]["Mount"]; + mountId: string; + name: string; + path: string; + receiver?: components["schemas"]["Receiver"]; + /** Format: double */ + score: number; + /** Format: int64 */ + size: number; + tags: { + [key: string]: string[] | undefined; + }; + type: string; + vaultRepo?: components["schemas"]["BundleVaultRepo"]; + }; + SearchResult: { + hits: components["schemas"]["SearchHit"][]; + mounts: { + [key: string]: components["schemas"]["Mount"] | undefined; + }; + }; + SettingsLanguage: { + officeOnlineDataLocale?: string; + officeOnlineLocale?: string; + preferred?: string; + }; + SettingsNotifications: { + deviceOffline: boolean; + newComment: boolean; + shared: boolean; + }; + SettingsSecurity: { + downloadLinkAutoPassword: boolean; + downloadLinkRequirePassword: boolean; + uploadLinkAutoPassword: boolean; + uploadLinkRequirePassword: boolean; + }; + SettingsSeen: { + desktop?: boolean; + intro?: boolean; + officeOnline?: boolean; + }; + Shared: { + files: components["schemas"]["SharedFile"][]; + }; + SharedFile: { + contentType: string; + link?: components["schemas"]["Link"]; + /** Format: int64 */ + modified: number; + mount: components["schemas"]["Mount"]; + name: string; + receiver?: components["schemas"]["Receiver"]; + /** Format: int64 */ + size: number; + type: string; + }; + Snapshot: { + /** Format: int64 */ + created: number; + /** Format: int64 */ + files: number; + name: string; + /** Format: int64 */ + size: number; + state: string; + }; + Trash: { + files: components["schemas"]["TrashFile"][]; + mounts: { + [key: string]: components["schemas"]["Mount"] | undefined; + }; + pageInfo: components["schemas"]["TrashPageInfo"]; + /** Format: int32 */ + retentionDays: number; + }; + TrashFile: { + contentType: string; + /** Format: int64 */ + deleted: number; + mountId: string; + name: string; + path: string; + /** Format: int64 */ + size: number; + tags: { + [key: string]: string[] | undefined; + }; + versionId: string; + }; + TrashPageInfo: { + cursor?: string; + }; + /** @description User represents the user structure. */ + User: { + email: string; + firstName: string; + hasPassword: boolean; + /** + * @description Id is the unique id of the user. + * @example 12341234-1234-1234-1234-123412341234 + */ + id: string; + lastName: string; + /** Format: int32 */ + level: number; + phoneNumber?: string; + }; + /** @description UserAttributes represents user attributes. By default it has only hasCloud property but it might return others. */ + UserAttributes: { + hasCloud: boolean; + }; + UserChangeEmail: { + newEmail: string; + }; + UserChangePassword: { + newPassword: string; + oldPassword?: string; + }; + /** @description UserEdit represents the user edit structure. */ + UserEdit: { + firstName: string; + lastName: string; + }; + UserInfo: { + email: string; + id: string; + name: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export interface operations { + applicationsList: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["AppInstances"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + applicationsRevoke: { + parameters: { + query?: never; + header?: never; + path: { + clientId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + basicConfig: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["BasicConfig"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + changelog: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Changelog"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + changelogOpened: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ChangelogOpened"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Changelog"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + changelogSeen: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ChangelogSeen"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Changelog"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devices: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Devices"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesNew: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["DeviceCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Device"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesDetails: { + parameters: { + query?: never; + header?: never; + path: { + deviceId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Device"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesEdit: { + parameters: { + query?: never; + header?: never; + path: { + deviceId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesDelete: { + parameters: { + query?: never; + header?: never; + path: { + deviceId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesReauth: { + parameters: { + query?: never; + header?: never; + path: { + deviceId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Redirect */ + 303: { + headers: { + /** @description Redirect location */ + Location?: string; + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + devicesEditSearch: { + parameters: { + query?: never; + header?: never; + path: { + deviceId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["DeviceSearch"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groups: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Groups"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsDetails: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Group"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsAttributes: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": Record; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsBrandingLogoRemove: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsCommonEdit: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["GroupCommonUpdate"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsUsersAdd: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["GroupUserCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["GroupUser"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsUsersEdit: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + groupUserId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["GroupUserEdit"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsUsersRemove: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + groupUserId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobs: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Jobs"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsRemoveCompleted: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsFilesCopy: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobCopy"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Nothing to do. This can occur when all items have conflict and the conflict resolution is SKIP. */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request data */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Some job items failed checks */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["JobFileDestErrors"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsFilesImportLink: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobCopy"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Invalid request data, Link not found or Invalid password */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsFilesMove: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobCopy"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Nothing to do. This can occur when all items have conflict and the conflict resolution is SKIP. */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request data */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Some job items failed checks */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["JobFileDestErrors"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsFilesRemove: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobRemove"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsFilesRestoreSnapshot: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobCopy"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Invalid request data */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsDetails: { + parameters: { + query?: never; + header?: never; + path: { + jobId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsRemove: { + parameters: { + query?: never; + header?: never; + path: { + jobId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + jobsAbort: { + parameters: { + query?: never; + header?: never; + path: { + jobId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksAll: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["LinksBundle"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mounts: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Mounts"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsDetails: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Mount"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsEdit: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["MountEdit"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request body */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsDelete: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + bundle: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Bundle"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + comments: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Comments"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + commentsNew: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["CommentCreate"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Comment"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + commentsRange: { + parameters: { + query: { + from: number; + limit: number; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Comments"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + commentsDetails: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + commentId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Comment"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + commentsDelete: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + commentId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesCopy: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesCopy"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesCopyResult"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesCreate: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + template: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesCreateResult"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesGetLink: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesGetLink"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesExternal: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Redirect */ + 303: { + headers: { + /** @description Redirect location */ + Location?: string; + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesExternalStatus: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesExternalStatus"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesFolderNew: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFolderCreate"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesGet: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Redirect */ + 303: { + headers: { + /** @description Redirect location */ + Location?: string; + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesInfo: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesList: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Files"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesMove: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesMove"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesMoveResult"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesRemove: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesRemove"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesRename: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesRename"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesTagsAdd: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesTagsAdd"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesTagsRemove: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesTagsRemove"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesTagsSet: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["FilesTagsSet"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesUpload: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesUploadLink"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesVersions: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesVersions"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesChangeVersion: { + parameters: { + query: { + path: string; + version: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesVersionsRecover: { + parameters: { + query: { + path: string; + version: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesVersionsRecover"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsGroupsAdd: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + mountGroupId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["MountGroupCreate"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request body or mount or group does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsGroupsRemove: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + mountGroupId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount or user does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + links: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Links"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksCreate: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Limit exceeded */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksDetails: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksDelete: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksCounter: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["LinkCounter"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksSetDownloadable: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkSetDownloadable"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksSetMessage: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkMessage"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksRemovePassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksResetPassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksSetPassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkSetPassword"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksQr: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksSetUrlHash: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkSetHash"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + linksSetValidity: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + linkId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["LinkValidity"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Link"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Limit exceeded */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsReauth: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Redirect */ + 303: { + headers: { + /** @description Redirect location */ + Location?: string; + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount does not exist or not mount owner */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receivers: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receivers"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversCreate: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Limit exceeded */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversDetails: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversDelete: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversSetAlert: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverSetAlert"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversSetMessage: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverMessage"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversRemovePassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversResetPassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversSetPassword: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverSetPassword"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversQr: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversSetUrlHash: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverSetHash"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversSetValidity: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + receiverId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiverValidity"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Receiver"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Limit exceeded */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsSubmountsCreate: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["MountCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Mount"]; + }; + }; + /** @description Invalid request body, mount or path does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsUsersAdd: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["MountUserCreate"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["MountUser"]; + }; + }; + /** @description Invalid request body or mount does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Multiple users with same email found */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["MountCandidate"][]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsUsersEdit: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + mountUserId: string; + }; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["MountUserEdit"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request body or mount or user does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + mountsUsersRemove: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + mountUserId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Mount or user does not exist */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + places: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Places"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + receiversAll: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ReceiversBundle"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + search: { + parameters: { + query?: { + /** + * @description Search query term + * @example lorem ipsum + */ + query?: string; + /** + * @description Pagination offset (default: 0) + * @example 0 + */ + offset?: number; + /** + * @description Max number of search results (default: 256, max: 1000) + * @example 256 + */ + limit?: number; + /** + * @description Sort field name + * @example name + */ + sortField?: "name" | "type" | "size" | "modified" | "contentType"; + /** + * @description Sort direction (default: asc) + * @example asc + */ + sortDir?: "asc" | "desc"; + /** + * @description Filter by mount ID + * @example 12341234-1234-1234-1234-123412341234 + */ + mountId?: string; + /** + * @description Filter by path (`mountId` is required if `path` is specified) + * @example /example/path + */ + path?: string; + /** + * @description Filter by content type / mime type + * @example text/plain + */ + contentType?: string; + /** + * @description Filter by file type + * @example file + */ + fileType?: + | "file" + | "folder" + | "pdf" + | "document" + | "sheet" + | "presentation" + | "archive" + | "code" + | "text" + | "audio" + | "video" + | "image"; + /** + * @description Filter by tag value (key=value pairs) + * @example priority=low + */ + tag?: string[]; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SearchResult"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + shared: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Shared"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + sharedDetails: { + parameters: { + query?: never; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SharedFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + snapshots: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["MountsSnapshots"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + trash: { + parameters: { + query?: { + /** @description Page cursor */ + cursor?: string; + /** + * @description Max number of items per page + * @example 256 + */ + pageSize?: number; + /** + * @description Sort field name + * @example name + */ + sortField?: "name" | "path" | "size" | "deleted"; + /** + * @description Sort direction (default: asc) + * @example asc + */ + sortDir?: "asc" | "desc"; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Trash"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + trashEmpty: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + trashUndelete: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Specific files can be undeleted by providing their mount ID and paths. If the files list is empty, all files will be undeleted. */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["JobUndelete"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Job"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + user: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["User"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New user's info */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["UserEdit"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + activity: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Activity"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userAppConfig: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["AppConfig"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + appPasswordsList: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["AppPasswords"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + appPasswordsGenerate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["AppPasswordGenerate"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["AppPassword"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + appPasswordsRevoke: { + parameters: { + query?: never; + header?: never; + path: { + apwId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userAttributes: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["UserAttributes"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userAuthenticated: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + bookmarks: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Bookmarks"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + bookmarksEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["Bookmarks"]; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Bookmarks"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + bookmarksCreate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["Bookmark"]; + }; + }; + responses: { + /** @description Success */ + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + bookmarksRemove: { + parameters: { + query: { + mountId: string; + path: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bookmark not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userChangeEmail: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["UserChangeEmail"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + connections: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Connections"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userChangePassword: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description TODO */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["UserChangePassword"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + brandingLogoRemove: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsLanguage: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsLanguage"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsLanguageEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New settings */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsLanguage"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsNotifications: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsNotifications"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsNotificationsEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New settings */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsNotifications"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsSecurity: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsSecurity"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsSecurityEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New settings */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsSecurity"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsSeen: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsSeen"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + settingsSeenEdit: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New settings */ + requestBody?: { + content: { + "application/json; charset=utf-8": components["schemas"]["SettingsSeen"]; + }; + }; + responses: { + /** @description Success */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGetMulti: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description A list of mountId:path pairs of the files to be included in the ZIP archive. Max body size is 10 MB. */ + requestBody?: { + content: { + "application/x-www-form-urlencoded": { + /** + * @description A list of `mountId:path` pairs + * @example [ + * "11111111-1111-1111-1111-111111111111:/example/path1", + * "22222222-2222-2222-2222-222222222222:/example/path2" + * ] + */ + files?: string[]; + }; + }; + }; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGetMultiName: { + parameters: { + query?: never; + header?: never; + path: { + name: string; + }; + cookie?: never; + }; + /** @description A list of `mountId:path` pairs of the files to be included in the ZIP archive. Max body size is 10 MB. */ + requestBody?: { + content: { + "application/x-www-form-urlencoded": { + /** + * @description A list of `mountId:path` pairs + * @example [ + * "11111111-1111-1111-1111-111111111111:/example/path1", + * "22222222-2222-2222-2222-222222222222:/example/path2" + * ] + */ + files?: string[]; + }; + }; + }; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsContentGroupsBrandingLogo: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + groupsContentGroupsBrandingLogoUpdate: { + parameters: { + query?: never; + header?: never; + path: { + groupId: string; + }; + cookie?: never; + }; + /** @description New branding logo file */ + requestBody?: { + content: { + "application/octet-stream": string; + "multipart/form-data": { + /** Format: binary */ + file?: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGet: { + parameters: { + query: { + path: string; + /** + * @description Forces the web browsers to download the file. Adds the `Content-Disposition: attachment; filename="file.txt"; filename*=UTF-8''file.txt` header. + * @example true + */ + force?: boolean; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGetPost: { + parameters: { + query: { + path: string; + /** + * @description Forces the web browsers to download the file. Adds the `Content-Disposition: attachment; filename="file.txt"; filename*=UTF-8''file.txt` header. + * @example true + */ + force?: boolean; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description A list of names of the files to be included in the ZIP archive. Filtered folders will include their children. Max body size is 10 MB. */ + requestBody?: { + content: { + "application/x-www-form-urlencoded": { + /** + * @description A list of names to include + * @example [ + * "file.txt", + * "folder1", + * "folder2" + * ] + */ + files?: string[]; + }; + }; + }; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGetName: { + parameters: { + query: { + path: string; + /** + * @description Forces the web browsers to download the file. Adds the `Content-Disposition: attachment; filename="file.txt"; filename*=UTF-8''file.txt` header. + * @example true + */ + force?: boolean; + }; + header?: never; + path: { + mountId: string; + name: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesGetNamePost: { + parameters: { + query: { + path: string; + /** + * @description Forces the web browsers to download the file. Adds the `Content-Disposition: attachment; filename="file.txt"; filename*=UTF-8''file.txt` header. + * @example true + */ + force?: boolean; + }; + header?: never; + path: { + mountId: string; + name: string; + }; + cookie?: never; + }; + /** @description A list of names of the files to be included in the ZIP archive. Filtered folders will include their children. Max body size is 10 MB. */ + requestBody?: { + content: { + "application/x-www-form-urlencoded": { + /** + * @description A list of names to include + * @example [ + * "file.txt", + * "folder1", + * "folder2" + * ] + */ + files?: string[]; + }; + }; + }; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesListRecursive: { + parameters: { + query: { + path: string; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Newline-delimited JSON files */ + 200: { + headers: { + /** @description Chunked encoding */ + "Transfer-Encoding"?: "chunked"; + [name: string]: unknown; + }; + content: { + "application/x-ndjson; charset=utf-8": components["schemas"]["FilesListRecursiveItem"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + filesContentFilesPut: { + parameters: { + query: { + path: string; + /** + * @description Name of the uploaded file. If this parameter is not set and multipart body is used, the file name from the multipart body will be used (this parameter takes precedence). If raw request body is used this parameter is required. + * @example file.txt + */ + filename?: string; + /** + * @description Return full file info (`FilesFile`) in the response. + * @example true + */ + info?: boolean; + /** + * @description Overwrite an existing file. + * @example false + */ + overwrite?: boolean; + /** + * @description Overwrite an existing file if modified matches. + * @example 1614877008000 + */ + overwriteIfModified?: number; + /** + * @description Overwrite an existing file if size matches. + * @example 42 + */ + overwriteIfSize?: number; + /** + * @description Overwrite an existing file if hash matches. + * @example 1a79a4d60de6718e8e5b326e338ae533 + */ + overwriteIfHash?: string; + /** + * @description Overwrite an existing file if other parameters match (e.g. overWriteIfModified) but create a new file if the old one does not exist. + * @example false + */ + overwriteIgnoreNonexistent?: boolean; + /** + * @description Overwrite an existing file. + * @example false + */ + autorename?: boolean; + /** + * @description Set custom value for modified. Current time by default. + * @example 1614877008000 + */ + modified?: number; + /** + * @description Tags for the new file. Format: key=value + * @example description=File description + */ + tags?: string[]; + }; + header?: never; + path: { + mountId: string; + }; + cookie?: never; + }; + /** @description File */ + requestBody?: { + content: { + "application/octet-stream": string; + "multipart/form-data": { + /** Format: binary */ + file?: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userProfilePictureContentProfilePicture: { + parameters: { + query?: { + /** + * @description Controls whether the response contains the default profile picture or 404 not found in case the user does not have a custom profile picture set. + * @example true + */ + nodefault?: boolean; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + userProfilePictureContentProfilePictureUpdate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New profile picture file */ + requestBody?: { + content: { + "application/octet-stream": string; + "multipart/form-data": { + /** Format: binary */ + file?: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + brandingContentBrandingLogo: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + brandingContentBrandingLogoUpdate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description New branding logo file */ + requestBody?: { + content: { + "application/octet-stream": string; + "multipart/form-data": { + /** Format: binary */ + file?: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["FilesFile"]; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + usersProfilePictureContentProfilePicture: { + parameters: { + query?: { + /** + * @description Controls whether the response contains the default profile picture or 404 not found in case the user does not have a custom profile picture set. + * @example true + */ + nodefault?: boolean; + }; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description File */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/octet-stream": string; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + clientIp: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Client's IP address (without trailing new line) */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + oauth2DeviceCode: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + oauth2Token: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; + profile: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["Profile"]; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json; charset=utf-8": components["schemas"]["ApiError"]; + }; + }; + }; + }; +} diff --git a/pro/src/langs/en.json b/pro/src/langs/en.json index 9159b83..da83a52 100644 --- a/pro/src/langs/en.json +++ b/pro/src/langs/en.json @@ -22,6 +22,11 @@ "protocol_yandexdisk_connect_fail": "Something went wrong from response from Yandex Disk website. Maybe the network connection is not good. Maybe you rejected the auth?", "protocol_yandexdisk_connect_succ_revoke": "You've connected. If you want to disconnect, click this button.", + "protocol_koofr_connecting": "Connectting", + "protocol_koofr_connect_manualinput_succ": "You've connected", + "protocol_koofr_connect_fail": "Something went wrong from response from Koofr website. Maybe the network connection is not good. Maybe you rejected the auth?", + "protocol_koofr_connect_succ_revoke": "You've connected. If you want to disconnect, click this button.", + "modal_googledriveauth_tutorial": "

Please firstly go to the address, then go on the auth flow. In the end, you will see a code, please paste that code here and submit.

", "modal_googledriveauth_copybutton": "Click to copy the auth url", "modal_googledriveauth_copynotice": "The auth url is copied to the clipboard!", @@ -76,6 +81,17 @@ "modal_yandexdiskrevokeauth_clean_notice": "Cleaned!", "modal_yandexdiskrevokeauth_clean_fail": "Something goes wrong while revoking.", + "modal_koofrauth_tutorial": "

Please firstly go to the address, then go on the auth flow. In the end, you will be redirected to here.

", + "modal_koofrauth_copybutton": "Click to copy the auth url", + "modal_koofrauth_copynotice": "The auth url is copied to the clipboard!", + "modal_koofrrevokeauth_step1": "Step 1: Go to the following address, you can remove the connection there.", + "modal_koofrrevokeauth_step2": "Step 2: Click the button below, to clean the locally-saved login credentials.", + "modal_koofrrevokeauth_clean": "Clean Locally-Saved Login Credentials", + "modal_koofrrevokeauth_clean_desc": "You need to click the button.", + "modal_koofrrevokeauth_clean_button": "Clean", + "modal_koofrrevokeauth_clean_notice": "Cleaned!", + "modal_koofrrevokeauth_clean_fail": "Something goes wrong while revoking.", + "modal_prorevokeauth": "Revoke auth by clicking here and follow the steps.", "modal_prorevokeauth_clean": "Clean", "modal_prorevokeauth_clean_desc": "Clean local auth record", @@ -165,10 +181,29 @@ "settings_yandexdisk_connect_succ": "Great! We can connect to Yandex Disk!", "settings_yandexdisk_connect_fail": "We cannot connect to Yandex Disk.", + "settings_koofr": "Koofr (PRO) (beta)", + "settings_chooseservice_koofr": "Koofr (PRO) (beta)", + "settings_koofr_disclaimer1": "Disclaimer: This app is NOT an official Koofr product. The app just uses Koofr's public api.", + "settings_koofr_disclaimer2": "Disclaimer: The information is stored locally. Other malicious/harmful/faulty plugins could read the info. If you see any unintentional access to your Koofr, please immediately disconnect this app on https://app.koofr.net/app/admin/preferences/security .", + "settings_koofr_pro_desc": "

!!It's a PRO feature of Remotely Save! You need a Remotely Save online account for this feature!!(scroll down for more info about PRO account.)

", + "settings_koofr_notshowuphint": "Koofr Settings Not Available", + "settings_koofr_notshowuphint_desc": "Koofr settings are not available, because you haven't subscribed to the PRO feature in your Remotely Save account.", + "settings_koofr_notshowuphint_view_pro": "View PRO Settings", + "settings_koofr_folder": "We will create and sync inside the folder {{remoteBaseDir}} on your Koofr. DO NOT create this folder by yourself manually.", + "settings_koofr_revoke": "Revoke Auth", + "settings_koofr_revoke_desc": "You've connected. If you want to disconnect, click this button.", + "settings_koofr_revoke_button": "Revoke Auth", + "settings_koofr_auth": "Auth", + "settings_koofr_auth_desc": "Auth.", + "settings_koofr_auth_button": "Auth", + "settings_koofr_connect_succ": "Great! We can connect to Koofr!", + "settings_koofr_connect_fail": "We cannot connect to Koofr.", + "settings_export_googledrive_button": "Export Google Drive Part", "settings_export_box_button": "Export Box Part", "settings_export_pcloud_button": "Export pCloud Part", "settings_export_yandexdisk_button": "Export Yandex Disk Part", + "settings_export_koofr_button": "Export Koofr Part", "settings_pro": "Account (for PRO features)", "settings_pro_tutorial": "

Using basic features of Remotely Save is FREE and do NOT need an account.

However, you will need an online account and PAY for the PRO features such as smart conflict.

Firstly please click the button to sign up and sign in to the website: https://remotelysave.com. Notice: It's different from, and NOT affiliated with Obsidian account.

Secondly please \"connect\" your local device to your online account.", diff --git a/pro/src/langs/zh_cn.json b/pro/src/langs/zh_cn.json index 57c1d8a..022406f 100644 --- a/pro/src/langs/zh_cn.json +++ b/pro/src/langs/zh_cn.json @@ -22,6 +22,11 @@ "protocol_yandexdisk_connect_fail": "Yandex Disk 官网返回错误。可能是网络连接不稳定。也可能是您拒绝了授权?", "protocol_yandexdisk_connect_succ_revoke": "您已连接上账号。如果要取消连接,请点击此按钮。", + "protocol_koofr_connecting": "正在连接", + "protocol_koofr_connect_manualinput_succ": "连接成功", + "protocol_koofr_connect_fail": "Yandex Disk 官网返回错误。可能是网络连接不稳定。也可能是您拒绝了授权?", + "protocol_koofr_connect_succ_revoke": "您已连接上账号。如果要取消连接,请点击此按钮。", + "modal_googledriveauth_tutorial": "

请访问此网址,然后会进入授权流程。最后,您会看到一个码,请复制粘贴到这里然后提交。

", "modal_googledriveauth_copybutton": "点击以复制网址", "modal_googledriveauth_copynotice": "网址已复制!", @@ -81,6 +86,22 @@ "modal_yandexdiskrevokeauth_clean_notice": "已清理!", "modal_yandexdiskrevokeauth_clean_fail": "清理授权时候发生了错误。", + "modal_koofrauth_tutorial": "

请访问此网址,然后会进入授权流程。最后,您会被重定向回来。

", + "modal_koofrauth_copybutton": "点击以复制网址", + "modal_koofrauth_copynotice": "网址已复制!", + "modal_koofr_maualinput": "网站上的码", + "modal_koofr_maualinput_desc": "请粘贴授权流程最后的那个码,然后点击确认。", + "modal_koofr_maualinput_notice": "正在尝试连接 Yandex Disk 并更新授权信息......", + "modal_koofr_maualinput_succ_notice": "很好!授权信息已更新!", + "modal_koofr_maualinput_fail_notice": "更新授权信息失败。请稍后重试。", + "modal_koofrrevokeauth_step1": "第 1 步:访问以下网址,可以删除连接。", + "modal_koofrrevokeauth_step2": "第 2 步:点击以下按钮,从而清理本地的登录信息。", + "modal_koofrrevokeauth_clean": "清理本地登录信息", + "modal_koofrrevokeauth_clean_desc": "您需要点击此按钮。", + "modal_koofrrevokeauth_clean_button": "清理", + "modal_koofrrevokeauth_clean_notice": "已清理!", + "modal_koofrrevokeauth_clean_fail": "清理授权时候发生了错误。", + "modal_prorevokeauth": "点击这里和按照步骤取消授权。", "modal_prorevokeauth_clean": "清理", "modal_prorevokeauth_clean_desc": "清理本地授权记录", @@ -170,10 +191,29 @@ "settings_yandexdisk_connect_succ": "很好!我们可连接上 Yandex Disk!", "settings_yandexdisk_connect_fail": "我们未能连接上 Yandex Disk。", + "settings_koofr": "Koofr (PRO) (beta)", + "settings_chooseservice_koofr": "Koofr (PRO) (beta)", + "settings_koofr_disclaimer1": "声明:本插件不是 Koofr 的官方产品。只是用到了它的公开 API。", + "settings_koofr_disclaimer2": "声明:您所输入的信息存储于本地。其它有害的或者出错的插件,是有可能读取到这些信息的。如果您发现任何不符合预期的 Koofr 访问,请立刻在以下网站操作断开连接: https://app.koofr.net/app/admin/preferences/security 。", + "settings_koofr_pro_desc": "

!!这是 PRO(付费)功能! 您需要在线账号来使用此功能!!向下滑可以看到 PRO 账号的更多信息。)

", + "settings_koofr_notshowuphint": "Koofr 设置不可用", + "settings_koofr_notshowuphint_desc": "Koofr 设置不可用,因为您没有在 Remotely Save 账号里开启这个 PRO 功能。", + "settings_koofr_notshowuphint_view_pro": "查看 PRO 相关设置", + "settings_koofr_folder": "我们会在 Koofr 创建此文件夹并同步内容进去: {{remoteBaseDir}} 。请不要手动在网站上创建。", + "settings_koofr_revoke": "撤回鉴权", + "settings_koofr_revoke_desc": "您现在已连接。如果想取消连接,请点击此按钮。", + "settings_koofr_revoke_button": "撤回鉴权", + "settings_koofr_auth": "鉴权", + "settings_koofr_auth_desc": "鉴权.", + "settings_koofr_auth_button": "鉴权", + "settings_koofr_connect_succ": "很好!我们可连接上 Koofr!", + "settings_koofr_connect_fail": "我们未能连接上 Koofr。", + "settings_export_googledrive_button": "导出 Google Drive 部分", "settings_export_box_button": "导出 Box 部分", "settings_export_pcloud_button": "导出 pCloud 部分", "settings_export_yandexdisk_button": "导出 Yandex Disk 部分", + "settings_export_koofr_button": "导出 Koofr 部分", "settings_pro": "账号(PRO 付费功能)", "settings_pro_tutorial": "

使用 Remotely Save 的基本功能是免费的,而且需要注册对应账号。

但是,您需要注册账号和对PRO功能付费使用,如智能处理冲突功能。

第一步:点击按钮从而注册和登录网站:https://remotelysave.com。注意:这和 Obsidian 官方账号无关,是不同的账号。

第二部:点击“连接”按钮,从而连接本设备和在线账号。", diff --git a/pro/src/langs/zh_tw.json b/pro/src/langs/zh_tw.json index ed86616..6a43572 100644 --- a/pro/src/langs/zh_tw.json +++ b/pro/src/langs/zh_tw.json @@ -22,6 +22,11 @@ "protocol_yandexdisk_connect_fail": "Yandex Disk 官網返回錯誤。可能是網路連線不穩定。也可能是您拒絕了授權?", "protocol_yandexdisk_connect_succ_revoke": "您已連線上賬號。如果要取消連線,請點選此按鈕。", + "protocol_koofr_connecting": "正在連線", + "protocol_koofr_connect_manualinput_succ": "連線成功", + "protocol_koofr_connect_fail": "Yandex Disk 官網返回錯誤。可能是網路連線不穩定。也可能是您拒絕了授權?", + "protocol_koofr_connect_succ_revoke": "您已連線上賬號。如果要取消連線,請點選此按鈕。", + "modal_googledriveauth_tutorial": "

請訪問此網址,然後會進入授權流程。最後,您會看到一個碼,請複製貼上到這裡然後提交。

", "modal_googledriveauth_copybutton": "點選以複製網址", "modal_googledriveauth_copynotice": "網址已複製!", @@ -81,6 +86,22 @@ "modal_yandexdiskrevokeauth_clean_notice": "已清理!", "modal_yandexdiskrevokeauth_clean_fail": "清理授權時候發生了錯誤。", + "modal_koofrauth_tutorial": "

請訪問此網址,然後會進入授權流程。最後,您會被重定向回來。

", + "modal_koofrauth_copybutton": "點選以複製網址", + "modal_koofrauth_copynotice": "網址已複製!", + "modal_koofr_maualinput": "網站上的碼", + "modal_koofr_maualinput_desc": "請貼上授權流程最後的那個碼,然後點選確認。", + "modal_koofr_maualinput_notice": "正在嘗試連線 Yandex Disk 並更新授權資訊......", + "modal_koofr_maualinput_succ_notice": "很好!授權資訊已更新!", + "modal_koofr_maualinput_fail_notice": "更新授權資訊失敗。請稍後重試。", + "modal_koofrrevokeauth_step1": "第 1 步:訪問以下網址,可以刪除連線。", + "modal_koofrrevokeauth_step2": "第 2 步:點選以下按鈕,從而清理本地的登入資訊。", + "modal_koofrrevokeauth_clean": "清理本地登入資訊", + "modal_koofrrevokeauth_clean_desc": "您需要點選此按鈕。", + "modal_koofrrevokeauth_clean_button": "清理", + "modal_koofrrevokeauth_clean_notice": "已清理!", + "modal_koofrrevokeauth_clean_fail": "清理授權時候發生了錯誤。", + "modal_prorevokeauth": "點選這裡和按照步驟取消授權。", "modal_prorevokeauth_clean": "清理", "modal_prorevokeauth_clean_desc": "清理本地授權記錄", @@ -170,10 +191,29 @@ "settings_yandexdisk_connect_succ": "很好!我們可連線上 Yandex Disk!", "settings_yandexdisk_connect_fail": "我們未能連線上 Yandex Disk。", + "settings_koofr": "Koofr (PRO) (beta)", + "settings_chooseservice_koofr": "Koofr (PRO) (beta)", + "settings_koofr_disclaimer1": "宣告:本外掛不是 Koofr 的官方產品。只是用到了它的公開 API。", + "settings_koofr_disclaimer2": "宣告:您所輸入的資訊儲存於本地。其它有害的或者出錯的外掛,是有可能讀取到這些資訊的。如果您發現任何不符合預期的 Koofr 訪問,請立刻在以下網站操作斷開連線: https://app.koofr.net/app/admin/preferences/security 。", + "settings_koofr_pro_desc": "

!!這是 PRO(付費)功能! 您需要線上賬號來使用此功能!!向下滑可以看到 PRO 賬號的更多資訊。)

", + "settings_koofr_notshowuphint": "Koofr 設定不可用", + "settings_koofr_notshowuphint_desc": "Koofr 設定不可用,因為您沒有在 Remotely Save 賬號裡開啟這個 PRO 功能。", + "settings_koofr_notshowuphint_view_pro": "檢視 PRO 相關設定", + "settings_koofr_folder": "我們會在 Koofr 建立此資料夾並同步內容進去: {{remoteBaseDir}} 。請不要手動在網站上建立。", + "settings_koofr_revoke": "撤回鑑權", + "settings_koofr_revoke_desc": "您現在已連線。如果想取消連線,請點選此按鈕。", + "settings_koofr_revoke_button": "撤回鑑權", + "settings_koofr_auth": "鑑權", + "settings_koofr_auth_desc": "鑑權.", + "settings_koofr_auth_button": "鑑權", + "settings_koofr_connect_succ": "很好!我們可連線上 Koofr!", + "settings_koofr_connect_fail": "我們未能連線上 Koofr。", + "settings_export_googledrive_button": "匯出 Google Drive 部分", "settings_export_box_button": "匯出 Box 部分", "settings_export_pcloud_button": "匯出 pCloud 部分", "settings_export_yandexdisk_button": "匯出 Yandex Disk 部分", + "settings_export_koofr_button": "匯出 Koofr 部分", "settings_pro": "賬號(PRO 付費功能)", "settings_pro_tutorial": "

使用 Remotely Save 的基本功能是免費的,而且需要註冊對應賬號。

但是,您需要註冊賬號和對PRO功能付費使用,如智慧處理衝突功能。

第一步:點選按鈕從而註冊和登入網站:https://remotelysave.com。注意:這和 Obsidian 官方賬號無關,是不同的賬號。

第二部:點選“連線”按鈕,從而連線本裝置和線上賬號。", diff --git a/pro/src/settingsKoofr.ts b/pro/src/settingsKoofr.ts new file mode 100644 index 0000000..de2617b --- /dev/null +++ b/pro/src/settingsKoofr.ts @@ -0,0 +1,367 @@ +import cloneDeep from "lodash/cloneDeep"; +import { type App, Modal, Notice, Setting } from "obsidian"; +import { getClient } from "../../src/fsGetter"; +import type { TransItemType } from "../../src/i18n"; +import type RemotelySavePlugin from "../../src/main"; +import { stringToFragment } from "../../src/misc"; +import { ChangeRemoteBaseDirModal } from "../../src/settings"; +import { + DEFAULT_KOOFR_CONFIG, + generateAuthUrl, + sendRefreshTokenReq, +} from "./fsKoofr"; + +class KoofrAuthModal extends Modal { + readonly plugin: RemotelySavePlugin; + readonly authDiv: HTMLDivElement; + readonly revokeAuthDiv: HTMLDivElement; + readonly revokeAuthSetting: Setting; + readonly t: (x: TransItemType, vars?: any) => string; + constructor( + app: App, + plugin: RemotelySavePlugin, + authDiv: HTMLDivElement, + revokeAuthDiv: HTMLDivElement, + revokeAuthSetting: Setting, + t: (x: TransItemType, vars?: any) => string + ) { + super(app); + this.plugin = plugin; + this.authDiv = authDiv; + this.revokeAuthDiv = revokeAuthDiv; + this.revokeAuthSetting = revokeAuthSetting; + this.t = t; + } + + async onOpen() { + const { contentEl } = this; + const t = this.t; + + const authUrl = generateAuthUrl(this.plugin.settings.koofr.api, true); + const div2 = contentEl.createDiv(); + div2.createDiv({ + text: stringToFragment(t("modal_koofrauth_tutorial")), + }); + div2.createEl( + "button", + { + text: t("modal_koofrauth_copybutton"), + }, + (el) => { + el.onclick = async () => { + await navigator.clipboard.writeText(authUrl); + new Notice(t("modal_koofrauth_copynotice")); + }; + } + ); + + contentEl.createEl("p").createEl("a", { + href: authUrl, + text: authUrl, + }); + + // let refreshToken = ""; + // new Setting(contentEl) + // .setName(t("modal_koofr_maualinput")) + // .setDesc(t("modal_koofr_maualinput_desc")) + // .addText((text) => + // text + // .setPlaceholder("") + // .setValue("") + // .onChange((val) => { + // refreshToken = val.trim(); + // }) + // ) + // .addButton(async (button) => { + // button.setButtonText(t("submit")); + // button.onClick(async () => { + // new Notice(t("modal_koofr_maualinput_notice")); + + // try { + // if (this.plugin.settings.koofr === undefined) { + // this.plugin.settings.koofr = cloneDeep( + // DEFAULT_KOOFR_CONFIG + // ); + // } + // this.plugin.settings.koofr.refreshToken = refreshToken; + // this.plugin.settings.koofr.accessToken = "access"; + // this.plugin.settings.koofr.accessTokenExpiresAtTimeMs = 1; + // this.plugin.settings.koofr.accessTokenExpiresInMs = 1; + + // // TODO: abstraction leaking now, how to fix? + // const k = await sendRefreshTokenReq(refreshToken); + // const ts = Date.now(); + // this.plugin.settings.koofr.accessToken = k.access_token; + // this.plugin.settings.koofr.accessTokenExpiresInMs = + // k.expires_in * 1000; + // this.plugin.settings.koofr.accessTokenExpiresAtTimeMs = + // ts + k.expires_in * 1000 - 60 * 2 * 1000; + // await this.plugin.saveSettings(); + + // // try to remove data in clipboard + // await navigator.clipboard.writeText(""); + + // new Notice(t("modal_koofr_maualinput_succ_notice")); + // } catch (e) { + // console.error(e); + // new Notice(t("modal_koofr_maualinput_fail_notice")); + // } finally { + // this.authDiv.toggleClass( + // "koofr-auth-button-hide", + // this.plugin.settings.koofr.refreshToken !== "" + // ); + // this.revokeAuthDiv.toggleClass( + // "koofr-revoke-auth-button-hide", + // this.plugin.settings.koofr.refreshToken === "" + // ); + // this.close(); + // } + // }); + // }); + } + + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} + +class KoofrRevokeAuthModal extends Modal { + readonly plugin: RemotelySavePlugin; + readonly authDiv: HTMLDivElement; + readonly revokeAuthDiv: HTMLDivElement; + readonly t: (x: TransItemType, vars?: any) => string; + constructor( + app: App, + plugin: RemotelySavePlugin, + authDiv: HTMLDivElement, + revokeAuthDiv: HTMLDivElement, + t: (x: TransItemType, vars?: any) => string + ) { + super(app); + this.plugin = plugin; + this.authDiv = authDiv; + this.revokeAuthDiv = revokeAuthDiv; + this.t = t; + } + + async onOpen() { + const t = this.t; + const { contentEl } = this; + + contentEl.createEl("p", { + text: t("modal_koofrrevokeauth_step1"), + }); + const consentUrl = "https://app.koofr.net/app/admin/preferences/security"; + contentEl.createEl("p").createEl("a", { + href: consentUrl, + text: consentUrl, + }); + + contentEl.createEl("p", { + text: t("modal_koofrrevokeauth_step2"), + }); + + new Setting(contentEl) + .setName(t("modal_koofrrevokeauth_clean")) + .setDesc(t("modal_koofrrevokeauth_clean_desc")) + .addButton(async (button) => { + button.setButtonText(t("modal_koofrrevokeauth_clean_button")); + button.onClick(async () => { + try { + this.plugin.settings.koofr = cloneDeep(DEFAULT_KOOFR_CONFIG); + + await this.plugin.saveSettings(); + this.authDiv.toggleClass( + "koofr-auth-button-hide", + this.plugin.settings.koofr.refreshToken !== "" + ); + this.revokeAuthDiv.toggleClass( + "koofr-revoke-auth-button-hide", + this.plugin.settings.koofr.refreshToken === "" + ); + new Notice(t("modal_koofrrevokeauth_clean_notice")); + this.close(); + } catch (err) { + console.error(err); + new Notice(t("modal_koofrrevokeauth_clean_fail")); + } + }); + }); + } + + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} + +export const generateKoofrSettingsPart = ( + containerEl: HTMLElement, + t: (x: TransItemType, vars?: any) => string, + app: App, + plugin: RemotelySavePlugin, + saveUpdatedConfigFunc: () => Promise | undefined +) => { + const koofrDiv = containerEl.createEl("div", { + cls: "koofr-hide", + }); + koofrDiv.toggleClass("koofr-hide", plugin.settings.serviceType !== "koofr"); + koofrDiv.createEl("h2", { text: t("settings_koofr") }); + + const koofrLongDescDiv = koofrDiv.createEl("div", { + cls: "settings-long-desc", + }); + for (const c of [ + t("settings_koofr_disclaimer1"), + t("settings_koofr_disclaimer2"), + ]) { + koofrLongDescDiv.createEl("p", { + text: c, + cls: "koofr-disclaimer", + }); + } + + koofrLongDescDiv.createEl("p", { + text: t("settings_koofr_folder", { + remoteBaseDir: plugin.settings.koofr.remoteBaseDir || app.vault.getName(), + }), + }); + + koofrLongDescDiv.createDiv({ + text: stringToFragment(t("settings_koofr_pro_desc")), + cls: "koofr-disclaimer", + }); + + const koofrNotShowUpHintSetting = new Setting(koofrDiv) + .setName(t("settings_koofr_notshowuphint")) + .setDesc(t("settings_koofr_notshowuphint_desc")) + .addButton(async (button) => { + button.setButtonText(t("settings_koofr_notshowuphint_view_pro")); + button.onClick(async () => { + window.location.href = "#settings-pro"; + }); + }); + + const koofrAllowedToUsedDiv = koofrDiv.createDiv(); + // if pro enabled, show up; otherwise hide. + const allowKoofr = + plugin.settings.pro?.enabledProFeatures.filter( + (x) => x.featureName === "feature-koofr" + ).length === 1; + console.debug(`allow to show up koofr settings? ${allowKoofr}`); + if (allowKoofr) { + koofrAllowedToUsedDiv.removeClass("koofr-allow-to-use-hide"); + koofrNotShowUpHintSetting.settingEl.addClass("koofr-allow-to-use-hide"); + } else { + koofrAllowedToUsedDiv.addClass("koofr-allow-to-use-hide"); + koofrNotShowUpHintSetting.settingEl.removeClass("koofr-allow-to-use-hide"); + } + + const koofrSelectAuthDiv = koofrAllowedToUsedDiv.createDiv(); + const koofrAuthDiv = koofrSelectAuthDiv.createDiv({ + cls: "koofr-auth-button-hide settings-auth-related", + }); + const koofrRevokeAuthDiv = koofrSelectAuthDiv.createDiv({ + cls: "koofr-revoke-auth-button-hide settings-auth-related", + }); + + const koofrRevokeAuthSetting = new Setting(koofrRevokeAuthDiv) + .setName(t("settings_koofr_revoke")) + .setDesc(t("settings_koofr_revoke_desc")) + .addButton(async (button) => { + button.setButtonText(t("settings_koofr_revoke_button")); + button.onClick(async () => { + new KoofrRevokeAuthModal( + app, + plugin, + koofrAuthDiv, + koofrRevokeAuthDiv, + t + ).open(); + }); + }); + + new Setting(koofrAuthDiv) + .setName(t("settings_koofr_auth")) + .setDesc(t("settings_koofr_auth_desc")) + .addButton(async (button) => { + button.setButtonText(t("settings_koofr_auth_button")); + button.onClick(async () => { + const modal = new KoofrAuthModal( + app, + plugin, + koofrAuthDiv, + koofrRevokeAuthDiv, + koofrRevokeAuthSetting, + t + ); + plugin.oauth2Info.helperModal = modal; + plugin.oauth2Info.authDiv = koofrAuthDiv; + plugin.oauth2Info.revokeDiv = koofrRevokeAuthDiv; + plugin.oauth2Info.revokeAuthSetting = koofrRevokeAuthSetting; + modal.open(); + }); + }); + + koofrAuthDiv.toggleClass( + "koofr-auth-button-hide", + plugin.settings.koofr.refreshToken !== "" + ); + koofrRevokeAuthDiv.toggleClass( + "koofr-revoke-auth-button-hide", + plugin.settings.koofr.refreshToken === "" + ); + + let newkoofrRemoteBaseDir = plugin.settings.koofr.remoteBaseDir || ""; + new Setting(koofrAllowedToUsedDiv) + .setName(t("settings_remotebasedir")) + .setDesc(t("settings_remotebasedir_desc")) + .addText((text) => + text + .setPlaceholder(app.vault.getName()) + .setValue(newkoofrRemoteBaseDir) + .onChange((value) => { + newkoofrRemoteBaseDir = value.trim(); + }) + ) + .addButton((button) => { + button.setButtonText(t("confirm")); + button.onClick(() => { + new ChangeRemoteBaseDirModal( + app, + plugin, + newkoofrRemoteBaseDir, + "koofr" + ).open(); + }); + }); + new Setting(koofrAllowedToUsedDiv) + .setName(t("settings_checkonnectivity")) + .setDesc(t("settings_checkonnectivity_desc")) + .addButton(async (button) => { + button.setButtonText(t("settings_checkonnectivity_button")); + button.onClick(async () => { + new Notice(t("settings_checkonnectivity_checking")); + const client = getClient(plugin.settings, app.vault.getName(), () => + plugin.saveSettings() + ); + const errors = { msg: "" }; + const res = await client.checkConnect((err: any) => { + errors.msg = `${err}`; + }); + if (res) { + new Notice(t("settings_koofr_connect_succ")); + } else { + new Notice(t("settings_koofr_connect_fail")); + new Notice(errors.msg); + } + }); + }); + + return { + koofrDiv: koofrDiv, + koofrAllowedToUsedDiv: koofrAllowedToUsedDiv, + koofrNotShowUpHintSetting: koofrNotShowUpHintSetting, + }; +}; diff --git a/pro/src/settingsPro.ts b/pro/src/settingsPro.ts index 794f3cd..d6e61b3 100644 --- a/pro/src/settingsPro.ts +++ b/pro/src/settingsPro.ts @@ -255,7 +255,9 @@ export const generateProSettingsPart = ( pCloudAllowedToUsedDiv: HTMLDivElement, pCloudNotShowUpHintSetting: Setting, yandexDiskAllowedToUsedDiv: HTMLDivElement, - yandexDiskNotShowUpHintSetting: Setting + yandexDiskNotShowUpHintSetting: Setting, + koofrAllowedToUsedDiv: HTMLDivElement, + koofrNotShowUpHintSetting: Setting ) => { proDiv .createEl("h2", { text: t("settings_pro") }) @@ -372,6 +374,21 @@ export const generateProSettingsPart = ( ); } + const allowKoofr = + plugin.settings.pro?.enabledProFeatures.filter( + (x) => x.featureName === "feature-koofr" + ).length === 1; + console.debug(`allow to show up Koofr settings? ${allowKoofr}`); + if (allowKoofr) { + koofrAllowedToUsedDiv.removeClass("koofr-allow-to-use-hide"); + koofrNotShowUpHintSetting.settingEl.addClass("koofr-allow-to-use-hide"); + } else { + koofrAllowedToUsedDiv.addClass("koofr-allow-to-use-hide"); + koofrNotShowUpHintSetting.settingEl.removeClass( + "koofr-allow-to-use-hide" + ); + } + new Notice(t("settings_pro_features_refresh_succ")); }); }); diff --git a/src/baseTypes.ts b/src/baseTypes.ts index c473e5e..e37f233 100644 --- a/src/baseTypes.ts +++ b/src/baseTypes.ts @@ -6,6 +6,7 @@ import type { BoxConfig, GoogleDriveConfig, + KoofrConfig, PCloudConfig, ProConfig, YandexDiskConfig, @@ -23,7 +24,8 @@ export type SUPPORTED_SERVICES_TYPE = | "googledrive" | "box" | "pcloud" - | "yandexdisk"; + | "yandexdisk" + | "koofr"; export type SUPPORTED_SERVICES_TYPE_WITH_REMOTE_BASE_DIR = | "webdav" @@ -33,7 +35,8 @@ export type SUPPORTED_SERVICES_TYPE_WITH_REMOTE_BASE_DIR = | "googledrive" | "box" | "pcloud" - | "yandexdisk"; + | "yandexdisk" + | "koofr"; export interface S3Config { s3Endpoint: string; @@ -131,7 +134,8 @@ export type QRExportType = | "googledrive" | "box" | "pcloud" - | "yandexdisk"; + | "yandexdisk" + | "koofr"; export interface ProfilerConfig { enablePrinting?: boolean; @@ -148,6 +152,8 @@ export interface RemotelySavePluginSettings { box: BoxConfig; pcloud: PCloudConfig; yandexdisk: YandexDiskConfig; + koofr: KoofrConfig; + password: string; serviceType: SUPPORTED_SERVICES_TYPE; currLogLevel?: string; diff --git a/src/fsGetter.ts b/src/fsGetter.ts index 6c17ba5..15ad1fb 100644 --- a/src/fsGetter.ts +++ b/src/fsGetter.ts @@ -1,5 +1,6 @@ import { FakeFsBox } from "../pro/src/fsBox"; import { FakeFsGoogleDrive } from "../pro/src/fsGoogleDrive"; +import { FakeFsKoofr } from "../pro/src/fsKoofr"; import { FakeFsPCloud } from "../pro/src/fsPCloud"; import { FakeFsYandexDisk } from "../pro/src/fsYandexDisk"; import type { RemotelySavePluginSettings } from "./baseTypes"; @@ -65,6 +66,8 @@ export function getClient( vaultName, saveUpdatedConfigFunc ); + case "koofr": + return new FakeFsKoofr(settings.koofr, vaultName, saveUpdatedConfigFunc); default: throw Error(`cannot init client for serviceType=${settings.serviceType}`); } diff --git a/src/importExport.ts b/src/importExport.ts index ff123b8..a6aa4c3 100644 --- a/src/importExport.ts +++ b/src/importExport.ts @@ -28,6 +28,7 @@ export const exportQrCodeUri = async ( delete settings2.box; delete settings2.pcloud; delete settings2.yandexdisk; + delete settings2.koofr; delete settings2.pro; } else if (exportFields === "s3") { settings2 = { s3: cloneDeep(settings.s3) }; @@ -47,6 +48,8 @@ export const exportQrCodeUri = async ( settings2 = { pcloud: cloneDeep(settings.pcloud) }; } else if (exportFields === "yandexdisk") { settings2 = { yandexdisk: cloneDeep(settings.yandexdisk) }; + } else if (exportFields === "koofr") { + settings2 = { koofr: cloneDeep(settings.koofr) }; } delete settings2.vaultRandomID; diff --git a/src/main.ts b/src/main.ts index 548a7e8..a798bfd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,6 +25,7 @@ import { } from "../pro/src/account"; import { COMMAND_CALLBACK_BOX, + COMMAND_CALLBACK_KOOFR, COMMAND_CALLBACK_PCLOUD, COMMAND_CALLBACK_PRO, COMMAND_CALLBACK_YANDEXDISK, @@ -36,6 +37,11 @@ import { setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceBox, } from "../pro/src/fsBox"; import { DEFAULT_GOOGLEDRIVE_CONFIG } from "../pro/src/fsGoogleDrive"; +import { + DEFAULT_KOOFR_CONFIG, + sendAuthReq as sendAuthReqKoofr, + setConfigBySuccessfullAuthInplace as setConfigBySuccessfullAuthInplaceKoofr, +} from "../pro/src/fsKoofr"; import { type AuthAllowFirstRes as AuthAllowFirstResPCloud, DEFAULT_PCLOUD_CONFIG, @@ -106,6 +112,7 @@ const DEFAULT_SETTINGS: RemotelySavePluginSettings = { box: DEFAULT_BOX_CONFIG, pcloud: DEFAULT_PCLOUD_CONFIG, yandexdisk: DEFAULT_YANDEXDISK_CONFIG, + koofr: DEFAULT_KOOFR_CONFIG, password: "", serviceType: "s3", currLogLevel: "info", @@ -977,6 +984,64 @@ export default class RemotelySavePlugin extends Plugin { } ); + this.registerObsidianProtocolHandler( + COMMAND_CALLBACK_KOOFR, + async (inputParams) => { + if (this.oauth2Info.helperModal !== undefined) { + const k = this.oauth2Info.helperModal.contentEl; + k.empty(); + + t("protocol_koofr_connecting") + .split("\n") + .forEach((val) => { + k.createEl("p", { + text: val, + }); + }); + } + + console.debug(inputParams); + const authRes = await sendAuthReqKoofr( + this.settings.koofr.api, + inputParams.code, + async (e: any) => { + new Notice(t("protocol_koofr_connect_fail")); + new Notice(`${e}`); + throw e; + }, + true + ); + console.debug(authRes); + + const self = this; + await setConfigBySuccessfullAuthInplaceKoofr( + this.settings.koofr!, + authRes!, + () => self.saveSettings() + ); + + this.oauth2Info.verifier = ""; // reset it + this.oauth2Info.helperModal?.close(); // close it + this.oauth2Info.helperModal = undefined; + + this.oauth2Info.authDiv?.toggleClass( + "koofr-auth-button-hide", + this.settings.koofr?.refreshToken !== "" + ); + this.oauth2Info.authDiv = undefined; + + this.oauth2Info.revokeAuthSetting?.setDesc( + t("protocol_koofr_connect_succ_revoke") + ); + this.oauth2Info.revokeAuthSetting = undefined; + this.oauth2Info.revokeDiv?.toggleClass( + "koofr-revoke-auth-button-hide", + this.settings.koofr?.refreshToken === "" + ); + this.oauth2Info.revokeDiv = undefined; + } + ); + this.syncRibbon = this.addRibbonIcon( iconNameSyncWait, `${this.manifest.name}`, @@ -1275,6 +1340,10 @@ export default class RemotelySavePlugin extends Plugin { this.settings.yandexdisk = DEFAULT_YANDEXDISK_CONFIG; } + if (this.settings.koofr === undefined) { + this.settings.koofr = DEFAULT_KOOFR_CONFIG; + } + await this.saveSettings(); } @@ -1383,6 +1452,16 @@ export default class RemotelySavePlugin extends Plugin { needSave = true; } + let koofrExpired = false; + if ( + this.settings.koofr.refreshToken !== "" && + current >= this.settings!.koofr!.credentialsShouldBeDeletedAtTimeMs! + ) { + koofrExpired = true; + this.settings.koofr = cloneDeep(DEFAULT_KOOFR_CONFIG); + needSave = true; + } + if (this.settings.pro === undefined) { this.settings.pro = cloneDeep(DEFAULT_PRO_CONFIG); } @@ -1429,6 +1508,12 @@ export default class RemotelySavePlugin extends Plugin { 6000 ); } + if (koofrExpired) { + new Notice( + `${this.manifest.name}: You haven't manually auth koofr for many days, you need to re-auth it again.`, + 6000 + ); + } } async getVaultRandomIDFromOldConfigFile() { diff --git a/src/settings.ts b/src/settings.ts index 036687a..cf47d51 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -23,6 +23,7 @@ import type { import cloneDeep from "lodash/cloneDeep"; import { generateBoxSettingsPart } from "../pro/src/settingsBox"; import { generateGoogleDriveSettingsPart } from "../pro/src/settingsGoogleDrive"; +import { generateKoofrSettingsPart } from "../pro/src/settingsKoofr"; import { generatePCloudSettingsPart } from "../pro/src/settingsPCloud"; import { generateProSettingsPart } from "../pro/src/settingsPro"; import { generateYandexDiskSettingsPart } from "../pro/src/settingsYandexDisk"; @@ -1862,6 +1863,15 @@ export class RemotelySaveSettingTab extends PluginSettingTab { () => this.plugin.saveSettings() ); + ////////////////////////////////////////////////// + // below for koofr + ////////////////////////////////////////////////// + + const { koofrDiv, koofrAllowedToUsedDiv, koofrNotShowUpHintSetting } = + generateKoofrSettingsPart(containerEl, t, this.app, this.plugin, () => + this.plugin.saveSettings() + ); + ////////////////////////////////////////////////// // below for general chooser (part 2/2) ////////////////////////////////////////////////// @@ -1887,6 +1897,7 @@ export class RemotelySaveSettingTab extends PluginSettingTab { "yandexdisk", t("settings_chooseservice_yandexdisk") ); + dropdown.addOption("koofr", t("settings_chooseservice_koofr")); dropdown .setValue(this.plugin.settings.serviceType) @@ -1928,6 +1939,10 @@ export class RemotelySaveSettingTab extends PluginSettingTab { "yandexdisk-hide", this.plugin.settings.serviceType !== "yandexdisk" ); + koofrDiv.toggleClass( + "koofr-hide", + this.plugin.settings.serviceType !== "koofr" + ); await this.plugin.saveSettings(); }); }); @@ -2507,6 +2522,12 @@ export class RemotelySaveSettingTab extends PluginSettingTab { "yandexdisk" ).open(); }); + }) + .addButton(async (button) => { + button.setButtonText(t("settings_export_koofr_button")); + button.onClick(async () => { + new ExportSettingsQrCodeModal(this.app, this.plugin, "koofr").open(); + }); }); let importSettingVal = ""; @@ -2579,7 +2600,9 @@ export class RemotelySaveSettingTab extends PluginSettingTab { pCloudAllowedToUsedDiv, pCloudNotShowUpHintSetting, yandexDiskAllowedToUsedDiv, - yandexDiskNotShowUpHintSetting + yandexDiskNotShowUpHintSetting, + koofrAllowedToUsedDiv, + koofrNotShowUpHintSetting ); ////////////////////////////////////////////////// diff --git a/styles.css b/styles.css index 93222c2..f5f23d3 100644 --- a/styles.css +++ b/styles.css @@ -152,6 +152,25 @@ display: none; } +.koofr-disclaimer { + font-weight: bold; +} +.koofr-hide { + display: none; +} + +.koofr-allow-to-use-hide { + display: none; +} + +.koofr-auth-button-hide { + display: none; +} + +.koofr-revoke-auth-button-hide { + display: none; +} + .qrcode-img { width: 350px; height: 350px; diff --git a/tests/configPersist.test.ts b/tests/configPersist.test.ts index 77bee79..a357fc7 100644 --- a/tests/configPersist.test.ts +++ b/tests/configPersist.test.ts @@ -31,6 +31,9 @@ const DEFAULT_SETTINGS: RemotelySavePluginSettings = { yandexdisk: { refreshToken: "xxx", } as any, + koofr: { + refreshToken: "xxx", + } as any, password: "password", serviceType: "s3", currLogLevel: "info", diff --git a/webpack.config.js b/webpack.config.js index d4065df..28267c6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -18,6 +18,8 @@ const DEFAULT_PCLOUD_CLIENT_SECRET = process.env.PCLOUD_CLIENT_SECRET || ""; const DEFAULT_YANDEXDISK_CLIENT_ID = process.env.YANDEXDISK_CLIENT_ID || ""; const DEFAULT_YANDEXDISK_CLIENT_SECRET = process.env.YANDEXDISK_CLIENT_SECRET || ""; +const DEFAULT_KOOFR_CLIENT_ID = process.env.KOOFR_CLIENT_ID || ""; +const DEFAULT_KOOFR_CLIENT_SECRET = process.env.KOOFR_CLIENT_SECRET || ""; module.exports = { entry: "./src/main.ts", @@ -42,6 +44,8 @@ module.exports = { "process.env.DEFAULT_PCLOUD_CLIENT_SECRET": `"${DEFAULT_PCLOUD_CLIENT_SECRET}"`, "process.env.DEFAULT_YANDEXDISK_CLIENT_ID": `"${DEFAULT_YANDEXDISK_CLIENT_ID}"`, "process.env.DEFAULT_YANDEXDISK_CLIENT_SECRET": `"${DEFAULT_YANDEXDISK_CLIENT_SECRET}"`, + "process.env.DEFAULT_KOOFR_CLIENT_ID": `"${DEFAULT_KOOFR_CLIENT_ID}"`, + "process.env.DEFAULT_KOOFR_CLIENT_SECRET": `"${DEFAULT_KOOFR_CLIENT_SECRET}"`, }), // Work around for Buffer is undefined: // https://github.com/webpack/changelog-v5/issues/10