diff --git a/resources/scripts/api/account/index.ts b/resources/scripts/api/account/index.ts new file mode 100644 index 000000000..12c9b50ac --- /dev/null +++ b/resources/scripts/api/account/index.ts @@ -0,0 +1,61 @@ +import http, { getPaginationSet, PaginatedResult } from '@/api/http'; +import { Transformers, Server } from '@definitions/user'; +import { PanelPermissions } from '@/state/permissions'; + +interface QueryParams { + query?: string; + page?: number; + type?: string; +} + +const getServers = ({ query, ...params }: QueryParams): Promise> => { + return new Promise((resolve, reject) => { + http.get('/api/client', { + params: { + 'filter[*]': query, + ...params, + }, + }) + .then(({ data }) => resolve({ + items: (data.data || []).map(Transformers.toServer), + pagination: getPaginationSet(data.meta.pagination), + })) + .catch(reject); + }); +}; + +const getSystemPermissions = (): Promise => { + return new Promise((resolve, reject) => { + http.get('/api/client/permissions') + .then(({ data }) => resolve(data.attributes.permissions)) + .catch(reject); + }); +}; + +const updateAccountEmail = (email: string, password: string): Promise => { + return new Promise((resolve, reject) => { + http.put('/api/client/account/email', { email, password }) + .then(() => resolve()) + .catch(reject); + }); +}; + +interface UpdateAccountPasswordData { + current: string; + password: string; + confirmPassword: string; +} + +const updateAccountPassword = ({ current, password, confirmPassword }: UpdateAccountPasswordData): Promise => { + return new Promise((resolve, reject) => { + http.put('/api/client/account/password', { + current_password: current, + password: password, + password_confirmation: confirmPassword, + }) + .then(() => resolve()) + .catch(reject); + }); +}; + +export { getServers, getSystemPermissions, updateAccountEmail, updateAccountPassword }; diff --git a/resources/scripts/api/account/updateAccountEmail.ts b/resources/scripts/api/account/updateAccountEmail.ts deleted file mode 100644 index 5ff230265..000000000 --- a/resources/scripts/api/account/updateAccountEmail.ts +++ /dev/null @@ -1,9 +0,0 @@ -import http from '@/api/http'; - -export default (email: string, password: string): Promise => { - return new Promise((resolve, reject) => { - http.put('/api/client/account/email', { email, password }) - .then(() => resolve()) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/account/updateAccountPassword.ts b/resources/scripts/api/account/updateAccountPassword.ts deleted file mode 100644 index d59e85e9c..000000000 --- a/resources/scripts/api/account/updateAccountPassword.ts +++ /dev/null @@ -1,19 +0,0 @@ -import http from '@/api/http'; - -interface Data { - current: string; - password: string; - confirmPassword: string; -} - -export default ({ current, password, confirmPassword }: Data): Promise => { - return new Promise((resolve, reject) => { - http.put('/api/client/account/password', { - current_password: current, - password: password, - password_confirmation: confirmPassword, - }) - .then(() => resolve()) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/definitions/user/models.d.ts b/resources/scripts/api/definitions/user/models.d.ts index 70a0cf112..a721b2a66 100644 --- a/resources/scripts/api/definitions/user/models.d.ts +++ b/resources/scripts/api/definitions/user/models.d.ts @@ -1,5 +1,6 @@ import { Model, UUID } from '@/api/definitions'; -import { ServerEggVariable, ServerStatus } from '@/api/server/types'; + +export type ServerStatus = 'installing' | 'install_failed' | 'suspended' | 'restoring_backup' | null; interface SecurityKey extends Model { uuid: UUID; @@ -60,3 +61,57 @@ interface Server extends Model { variables: ServerEggVariable[]; allocations: Allocation[]; } + +interface ServerBackup extends Model { + uuid: UUID; + isSuccessful: boolean; + isLocked: boolean; + name: string; + ignoredFiles: string; + checksum: string; + bytes: number; + createdAt: Date; + completedAt: Date | null; +} + +interface ServerEggVariable extends Model { + name: string; + description: string; + envVariable: string; + defaultValue: string; + serverValue: string; + isEditable: boolean; + rules: string[]; +} + +interface ServerDatabase extends Model { + id: string; + name: string; + username: string; + connectionString: string; + allowConnectionsFrom: string; + password?: string; +} + +export type SubuserPermission = + 'websocket.connect' | + 'control.console' | 'control.start' | 'control.stop' | 'control.restart' | + 'user.create' | 'user.read' | 'user.update' | 'user.delete' | + 'file.create' | 'file.read' | 'file.update' | 'file.delete' | 'file.archive' | 'file.sftp' | + 'allocation.read' | 'allocation.update' | + 'startup.read' | 'startup.update' | + 'database.create' | 'database.read' | 'database.update' | 'database.delete' | 'database.view_password' | + 'schedule.create' | 'schedule.read' | 'schedule.update' | 'schedule.delete' + ; + +interface Subuser extends Model { + uuid: string; + username: string; + email: string; + image: string; + twoFactorEnabled: boolean; + createdAt: Date; + permissions: SubuserPermission[]; + + can (permission: SubuserPermission): boolean; +} diff --git a/resources/scripts/api/definitions/user/transformers.ts b/resources/scripts/api/definitions/user/transformers.ts index 1c1b841dc..9e2d6cb15 100644 --- a/resources/scripts/api/definitions/user/transformers.ts +++ b/resources/scripts/api/definitions/user/transformers.ts @@ -1,6 +1,5 @@ import * as Models from './models'; import { FractalResponseData, FractalResponseList } from '@/api/http'; -import { rawDataToServerEggVariable } from '@/api/transformers'; export default class Transformers { static toSecurityKey ({ attributes }: FractalResponseData): Models.SecurityKey { @@ -55,8 +54,59 @@ export default class Transformers { featureLimits: { ...attributes.feature_limits }, isInstalling: attributes.status === 'installing' || attributes.status === 'install_failed', isTransferring: attributes.is_transferring, - variables: ((attributes.relationships?.variables as FractalResponseList | undefined)?.data || []).map(rawDataToServerEggVariable), + variables: ((attributes.relationships?.variables as FractalResponseList | undefined)?.data || []).map(this.toServerEggVariable), allocations: ((attributes.relationships?.allocations as FractalResponseList | undefined)?.data || []).map(this.toServerAllocation), }; } + + static toServerBackup ({ attributes }: FractalResponseData): Models.ServerBackup { + return { + uuid: attributes.uuid, + isSuccessful: attributes.is_successful, + isLocked: attributes.is_locked, + name: attributes.name, + ignoredFiles: attributes.ignored_files, + checksum: attributes.checksum, + bytes: attributes.bytes, + createdAt: new Date(attributes.created_at), + completedAt: attributes.completed_at ? new Date(attributes.completed_at) : null, + }; + } + + static toServerEggVariable ({ attributes }: FractalResponseData): Models.ServerEggVariable { + return { + name: attributes.name, + description: attributes.description, + envVariable: attributes.env_variable, + defaultValue: attributes.default_value, + serverValue: attributes.server_value, + isEditable: attributes.is_editable, + rules: attributes.rules.split('|'), + }; + } + + static toServerDatabase ({ attributes }: FractalResponseData): Models.ServerDatabase { + return { + id: attributes.id, + name: attributes.name, + username: attributes.username, + connectionString: `${attributes.host.address}:${attributes.host.port}`, + allowConnectionsFrom: attributes.connections_from, + // @ts-expect-error + password: attributes.relationships && attributes.relationships.password ? attributes.relationships.password.attributes.password : undefined, + }; + } + + static toSubuser ({ attributes }: FractalResponseData): Models.Subuser { + return { + uuid: attributes.uuid, + username: attributes.username, + email: attributes.email, + image: attributes.image, + twoFactorEnabled: attributes['2fa_enabled'], + createdAt: new Date(attributes.created_at), + permissions: attributes.permissions || [], + can: permission => (attributes.permissions || []).indexOf(permission) >= 0, + }; + } } diff --git a/resources/scripts/api/getServers.ts b/resources/scripts/api/getServers.ts deleted file mode 100644 index f3b578874..000000000 --- a/resources/scripts/api/getServers.ts +++ /dev/null @@ -1,24 +0,0 @@ -import http, { getPaginationSet, PaginatedResult } from '@/api/http'; -import { Transformers, Server } from '@definitions/user'; - -interface QueryParams { - query?: string; - page?: number; - type?: string; -} - -export default ({ query, ...params }: QueryParams): Promise> => { - return new Promise((resolve, reject) => { - http.get('/api/client', { - params: { - 'filter[*]': query, - ...params, - }, - }) - .then(({ data }) => resolve({ - items: (data.data || []).map(Transformers.toServer), - pagination: getPaginationSet(data.meta.pagination), - })) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/getSystemPermissions.ts b/resources/scripts/api/getSystemPermissions.ts deleted file mode 100644 index 0e7f27caa..000000000 --- a/resources/scripts/api/getSystemPermissions.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { PanelPermissions } from '@/state/permissions'; -import http from '@/api/http'; - -export default (): Promise => { - return new Promise((resolve, reject) => { - http.get('/api/client/permissions') - .then(({ data }) => resolve(data.attributes.permissions)) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/backups.ts b/resources/scripts/api/server/backups.ts new file mode 100644 index 000000000..6e02e900f --- /dev/null +++ b/resources/scripts/api/server/backups.ts @@ -0,0 +1,47 @@ +import http from '@/api/http'; +import { ServerBackup, Transformers } from '@definitions/user'; + +const restoreServerBackup = async (uuid: string, backup: string, truncate?: boolean): Promise => { + await http.post(`/api/client/servers/${uuid}/backups/${backup}/restore`, { + truncate, + }); +}; + +interface CreateBackupParams { + name?: string; + ignored?: string; + isLocked: boolean; +} + +const createServerBackup = async (uuid: string, params: CreateBackupParams): Promise => { + const { data } = await http.post(`/api/client/servers/${uuid}/backups`, { + name: params.name, + ignored: params.ignored, + is_locked: params.isLocked, + }); + + return Transformers.toServerBackup(data); +}; + +const deleteBackup = (uuid: string, backup: string): Promise => { + return new Promise((resolve, reject) => { + http.delete(`/api/client/servers/${uuid}/backups/${backup}`) + .then(() => resolve()) + .catch(reject); + }); +}; + +const getBackupDownloadUrl = (uuid: string, backup: string): Promise => { + return new Promise((resolve, reject) => { + http.get(`/api/client/servers/${uuid}/backups/${backup}/download`) + .then(({ data }) => resolve(data.attributes.url)) + .catch(reject); + }); +}; + +export { + deleteBackup, + restoreServerBackup, + createServerBackup, + getBackupDownloadUrl, +}; diff --git a/resources/scripts/api/server/backups/createServerBackup.ts b/resources/scripts/api/server/backups/createServerBackup.ts deleted file mode 100644 index 3167b5b46..000000000 --- a/resources/scripts/api/server/backups/createServerBackup.ts +++ /dev/null @@ -1,19 +0,0 @@ -import http from '@/api/http'; -import { ServerBackup } from '@/api/server/types'; -import { rawDataToServerBackup } from '@/api/transformers'; - -interface RequestParameters { - name?: string; - ignored?: string; - isLocked: boolean; -} - -export default async (uuid: string, params: RequestParameters): Promise => { - const { data } = await http.post(`/api/client/servers/${uuid}/backups`, { - name: params.name, - ignored: params.ignored, - is_locked: params.isLocked, - }); - - return rawDataToServerBackup(data); -}; diff --git a/resources/scripts/api/server/backups/deleteBackup.ts b/resources/scripts/api/server/backups/deleteBackup.ts deleted file mode 100644 index 01f48d23f..000000000 --- a/resources/scripts/api/server/backups/deleteBackup.ts +++ /dev/null @@ -1,9 +0,0 @@ -import http from '@/api/http'; - -export default (uuid: string, backup: string): Promise => { - return new Promise((resolve, reject) => { - http.delete(`/api/client/servers/${uuid}/backups/${backup}`) - .then(() => resolve()) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/backups/getBackupDownloadUrl.ts b/resources/scripts/api/server/backups/getBackupDownloadUrl.ts deleted file mode 100644 index 70a3ae5e4..000000000 --- a/resources/scripts/api/server/backups/getBackupDownloadUrl.ts +++ /dev/null @@ -1,9 +0,0 @@ -import http from '@/api/http'; - -export default (uuid: string, backup: string): Promise => { - return new Promise((resolve, reject) => { - http.get(`/api/client/servers/${uuid}/backups/${backup}/download`) - .then(({ data }) => resolve(data.attributes.url)) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/backups/index.ts b/resources/scripts/api/server/backups/index.ts deleted file mode 100644 index 4f1311fdf..000000000 --- a/resources/scripts/api/server/backups/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import http from '@/api/http'; - -export const restoreServerBackup = async (uuid: string, backup: string, truncate?: boolean): Promise => { - await http.post(`/api/client/servers/${uuid}/backups/${backup}/restore`, { - truncate, - }); -}; diff --git a/resources/scripts/api/server/databases.ts b/resources/scripts/api/server/databases.ts new file mode 100644 index 000000000..843f10b6c --- /dev/null +++ b/resources/scripts/api/server/databases.ts @@ -0,0 +1,50 @@ +import http from '@/api/http'; +import { Transformers, ServerDatabase } from '@definitions/user'; + +const createServerDatabase = (uuid: string, data: { connectionsFrom: string; databaseName: string }): Promise => { + return new Promise((resolve, reject) => { + http.post(`/api/client/servers/${uuid}/databases`, { + database: data.databaseName, + remote: data.connectionsFrom, + }, { + params: { include: 'password' }, + }) + .then(response => resolve(Transformers.toServerDatabase(response.data.attributes))) + .catch(reject); + }); +}; + +const getServerDatabases = (uuid: string, includePassword = true): Promise => { + return new Promise((resolve, reject) => { + http.get(`/api/client/servers/${uuid}/databases`, { + params: includePassword ? { include: 'password' } : undefined, + }) + .then(response => resolve( + (response.data.data || []).map((item: any) => Transformers.toServerDatabase(item.attributes)) + )) + .catch(reject); + }); +}; + +const deleteServerDatabase = (uuid: string, database: string): Promise => { + return new Promise((resolve, reject) => { + http.delete(`/api/client/servers/${uuid}/databases/${database}`) + .then(() => resolve()) + .catch(reject); + }); +}; + +const rotateDatabasePassword = (uuid: string, database: string): Promise => { + return new Promise((resolve, reject) => { + http.post(`/api/client/servers/${uuid}/databases/${database}/rotate-password`) + .then((response) => resolve(Transformers.toServerDatabase(response.data))) + .catch(reject); + }); +}; + +export { + createServerDatabase, + getServerDatabases, + deleteServerDatabase, + rotateDatabasePassword, +}; diff --git a/resources/scripts/api/server/databases/createServerDatabase.ts b/resources/scripts/api/server/databases/createServerDatabase.ts deleted file mode 100644 index cf036f91f..000000000 --- a/resources/scripts/api/server/databases/createServerDatabase.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { rawDataToServerDatabase, ServerDatabase } from '@/api/server/databases/getServerDatabases'; -import http from '@/api/http'; - -export default (uuid: string, data: { connectionsFrom: string; databaseName: string }): Promise => { - return new Promise((resolve, reject) => { - http.post(`/api/client/servers/${uuid}/databases`, { - database: data.databaseName, - remote: data.connectionsFrom, - }, { - params: { include: 'password' }, - }) - .then(response => resolve(rawDataToServerDatabase(response.data.attributes))) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/databases/deleteServerDatabase.ts b/resources/scripts/api/server/databases/deleteServerDatabase.ts deleted file mode 100644 index 23275bd36..000000000 --- a/resources/scripts/api/server/databases/deleteServerDatabase.ts +++ /dev/null @@ -1,9 +0,0 @@ -import http from '@/api/http'; - -export default (uuid: string, database: string): Promise => { - return new Promise((resolve, reject) => { - http.delete(`/api/client/servers/${uuid}/databases/${database}`) - .then(() => resolve()) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/databases/getServerDatabases.ts b/resources/scripts/api/server/databases/getServerDatabases.ts deleted file mode 100644 index cf7c9037d..000000000 --- a/resources/scripts/api/server/databases/getServerDatabases.ts +++ /dev/null @@ -1,31 +0,0 @@ -import http from '@/api/http'; - -export interface ServerDatabase { - id: string; - name: string; - username: string; - connectionString: string; - allowConnectionsFrom: string; - password?: string; -} - -export const rawDataToServerDatabase = (data: any): ServerDatabase => ({ - id: data.id, - name: data.name, - username: data.username, - connectionString: `${data.host.address}:${data.host.port}`, - allowConnectionsFrom: data.connections_from, - password: data.relationships && data.relationships.password ? data.relationships.password.attributes.password : undefined, -}); - -export default (uuid: string, includePassword = true): Promise => { - return new Promise((resolve, reject) => { - http.get(`/api/client/servers/${uuid}/databases`, { - params: includePassword ? { include: 'password' } : undefined, - }) - .then(response => resolve( - (response.data.data || []).map((item: any) => rawDataToServerDatabase(item.attributes)) - )) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/databases/rotateDatabasePassword.ts b/resources/scripts/api/server/databases/rotateDatabasePassword.ts deleted file mode 100644 index 0e0619a84..000000000 --- a/resources/scripts/api/server/databases/rotateDatabasePassword.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { rawDataToServerDatabase, ServerDatabase } from '@/api/server/databases/getServerDatabases'; -import http from '@/api/http'; - -export default (uuid: string, database: string): Promise => { - return new Promise((resolve, reject) => { - http.post(`/api/client/servers/${uuid}/databases/${database}/rotate-password`) - .then((response) => resolve(rawDataToServerDatabase(response.data.attributes))) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/index.ts b/resources/scripts/api/server/index.ts index ba57ca90e..bed109c6e 100644 --- a/resources/scripts/api/server/index.ts +++ b/resources/scripts/api/server/index.ts @@ -1,7 +1,5 @@ import http from '@/api/http'; -import { Server, Transformers } from '@definitions/user'; -import { ServerEggVariable } from '@/api/server/types'; -import { rawDataToServerEggVariable } from '@/api/transformers'; +import { Server, ServerEggVariable, Transformers } from '@definitions/user'; interface TokenResponse { token: string; @@ -55,7 +53,7 @@ const setSelectedDockerImage = async (uuid: string, image: string): Promise => { const { data } = await http.put(`/api/client/servers/${uuid}/startup/variable`, { key, value }); - return [ rawDataToServerEggVariable(data), data.meta.startup_command ]; + return [ Transformers.toServerEggVariable(data), data.meta.startup_command ]; }; const getServerResourceUsage = async (server: string): Promise => { diff --git a/resources/scripts/api/server/network.ts b/resources/scripts/api/server/network.ts new file mode 100644 index 000000000..968f43134 --- /dev/null +++ b/resources/scripts/api/server/network.ts @@ -0,0 +1,30 @@ +import http from '@/api/http'; +import { Transformers, Allocation } from '@definitions/user'; + +const createServerAllocation = async (uuid: string): Promise => { + const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`); + + return Transformers.toServerAllocation(data); +}; + +const deleteServerAllocation = async (uuid: string, id: number): Promise => + await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`); + +const setPrimaryServerAllocation = async (uuid: string, id: number): Promise => { + const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`); + + return Transformers.toServerAllocation(data); +}; + +const setServerAllocationNotes = async (uuid: string, id: number, notes: string | null): Promise => { + const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes }); + + return Transformers.toServerAllocation(data); +}; + +export { + createServerAllocation, + deleteServerAllocation, + setPrimaryServerAllocation, + setServerAllocationNotes, +}; diff --git a/resources/scripts/api/server/network/createServerAllocation.ts b/resources/scripts/api/server/network/createServerAllocation.ts deleted file mode 100644 index 3e94cf7f6..000000000 --- a/resources/scripts/api/server/network/createServerAllocation.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Allocation } from '@/api/server/getServer'; -import http from '@/api/http'; -import { rawDataToServerAllocation } from '@/api/transformers'; - -export default async (uuid: string): Promise => { - const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`); - - return rawDataToServerAllocation(data); -}; diff --git a/resources/scripts/api/server/network/deleteServerAllocation.ts b/resources/scripts/api/server/network/deleteServerAllocation.ts deleted file mode 100644 index 92fd4b30a..000000000 --- a/resources/scripts/api/server/network/deleteServerAllocation.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Allocation } from '@/api/server/getServer'; -import http from '@/api/http'; - -export default async (uuid: string, id: number): Promise => await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`); diff --git a/resources/scripts/api/server/network/setPrimaryServerAllocation.ts b/resources/scripts/api/server/network/setPrimaryServerAllocation.ts deleted file mode 100644 index 27c09b722..000000000 --- a/resources/scripts/api/server/network/setPrimaryServerAllocation.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Allocation } from '@/api/server/getServer'; -import http from '@/api/http'; -import { rawDataToServerAllocation } from '@/api/transformers'; - -export default async (uuid: string, id: number): Promise => { - const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`); - - return rawDataToServerAllocation(data); -}; diff --git a/resources/scripts/api/server/network/setServerAllocationNotes.ts b/resources/scripts/api/server/network/setServerAllocationNotes.ts deleted file mode 100644 index 4531dc751..000000000 --- a/resources/scripts/api/server/network/setServerAllocationNotes.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Allocation } from '@/api/server/getServer'; -import http from '@/api/http'; -import { rawDataToServerAllocation } from '@/api/transformers'; - -export default async (uuid: string, id: number, notes: string | null): Promise => { - const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes }); - - return rawDataToServerAllocation(data); -}; diff --git a/resources/scripts/api/server/types.d.ts b/resources/scripts/api/server/types.d.ts deleted file mode 100644 index 7e3e540c0..000000000 --- a/resources/scripts/api/server/types.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -export type ServerStatus = 'installing' | 'install_failed' | 'suspended' | 'restoring_backup' | null; - -export interface ServerBackup { - uuid: string; - isSuccessful: boolean; - isLocked: boolean; - name: string; - ignoredFiles: string; - checksum: string; - bytes: number; - createdAt: Date; - completedAt: Date | null; -} - -export interface ServerEggVariable { - name: string; - description: string; - envVariable: string; - defaultValue: string; - serverValue: string; - isEditable: boolean; - rules: string[]; -} diff --git a/resources/scripts/api/server/users.ts b/resources/scripts/api/server/users.ts new file mode 100644 index 000000000..19cde1252 --- /dev/null +++ b/resources/scripts/api/server/users.ts @@ -0,0 +1,39 @@ +import http from '@/api/http'; +import { Transformers, Subuser } from '@definitions/user'; + +interface Params { + email: string; + permissions: string[]; +} + +const deleteSubuser = (uuid: string, userId: string): Promise => { + return new Promise((resolve, reject) => { + http.delete(`/api/client/servers/${uuid}/users/${userId}`) + .then(() => resolve()) + .catch(reject); + }); +}; + +const getServerSubusers = (uuid: string): Promise => { + return new Promise((resolve, reject) => { + http.get(`/api/client/servers/${uuid}/users`) + .then(({ data }) => resolve((data.data || []).map(Transformers.toSubuser))) + .catch(reject); + }); +}; + +const createOrUpdateSubuser = (uuid: string, params: Params, subuser?: Subuser): Promise => { + return new Promise((resolve, reject) => { + http.post(`/api/client/servers/${uuid}/users${subuser ? `/${subuser.uuid}` : ''}`, { + ...params, + }) + .then(data => resolve(Transformers.toSubuser(data.data))) + .catch(reject); + }); +}; + +export { + deleteSubuser, + getServerSubusers, + createOrUpdateSubuser, +}; diff --git a/resources/scripts/api/server/users/createOrUpdateSubuser.ts b/resources/scripts/api/server/users/createOrUpdateSubuser.ts deleted file mode 100644 index 93303a2db..000000000 --- a/resources/scripts/api/server/users/createOrUpdateSubuser.ts +++ /dev/null @@ -1,18 +0,0 @@ -import http from '@/api/http'; -import { rawDataToServerSubuser } from '@/api/server/users/getServerSubusers'; -import { Subuser } from '@/state/server/subusers'; - -interface Params { - email: string; - permissions: string[]; -} - -export default (uuid: string, params: Params, subuser?: Subuser): Promise => { - return new Promise((resolve, reject) => { - http.post(`/api/client/servers/${uuid}/users${subuser ? `/${subuser.uuid}` : ''}`, { - ...params, - }) - .then(data => resolve(rawDataToServerSubuser(data.data))) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/users/deleteSubuser.ts b/resources/scripts/api/server/users/deleteSubuser.ts deleted file mode 100644 index dccd98e69..000000000 --- a/resources/scripts/api/server/users/deleteSubuser.ts +++ /dev/null @@ -1,9 +0,0 @@ -import http from '@/api/http'; - -export default (uuid: string, userId: string): Promise => { - return new Promise((resolve, reject) => { - http.delete(`/api/client/servers/${uuid}/users/${userId}`) - .then(() => resolve()) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/server/users/getServerSubusers.ts b/resources/scripts/api/server/users/getServerSubusers.ts deleted file mode 100644 index 177bde815..000000000 --- a/resources/scripts/api/server/users/getServerSubusers.ts +++ /dev/null @@ -1,21 +0,0 @@ -import http, { FractalResponseData } from '@/api/http'; -import { Subuser } from '@/state/server/subusers'; - -export const rawDataToServerSubuser = (data: FractalResponseData): Subuser => ({ - uuid: data.attributes.uuid, - username: data.attributes.username, - email: data.attributes.email, - image: data.attributes.image, - twoFactorEnabled: data.attributes['2fa_enabled'], - createdAt: new Date(data.attributes.created_at), - permissions: data.attributes.permissions || [], - can: permission => (data.attributes.permissions || []).indexOf(permission) >= 0, -}); - -export default (uuid: string): Promise => { - return new Promise((resolve, reject) => { - http.get(`/api/client/servers/${uuid}/users`) - .then(({ data }) => resolve((data.data || []).map(rawDataToServerSubuser))) - .catch(reject); - }); -}; diff --git a/resources/scripts/api/swr/getServerAllocations.ts b/resources/scripts/api/swr/getServerAllocations.ts index a5591a396..899915852 100644 --- a/resources/scripts/api/swr/getServerAllocations.ts +++ b/resources/scripts/api/swr/getServerAllocations.ts @@ -1,8 +1,7 @@ import { ServerContext } from '@/state/server'; import useSWR from 'swr'; import http from '@/api/http'; -import { rawDataToServerAllocation } from '@/api/transformers'; -import { Allocation } from '@/api/server/getServer'; +import { Allocation, Transformers } from '@definitions/user'; export default () => { const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); @@ -10,6 +9,6 @@ export default () => { return useSWR([ 'server:allocations', uuid ], async () => { const { data } = await http.get(`/api/client/servers/${uuid}/network/allocations`); - return (data.data || []).map(rawDataToServerAllocation); + return (data.data || []).map(Transformers.toServerAllocation); }, { revalidateOnFocus: false, revalidateOnMount: false }); }; diff --git a/resources/scripts/api/swr/getServerBackups.ts b/resources/scripts/api/swr/getServerBackups.ts index 6b76ddcd1..1e5f493fe 100644 --- a/resources/scripts/api/swr/getServerBackups.ts +++ b/resources/scripts/api/swr/getServerBackups.ts @@ -1,7 +1,6 @@ import useSWR from 'swr'; import http, { getPaginationSet, PaginatedResult } from '@/api/http'; -import { ServerBackup } from '@/api/server/types'; -import { rawDataToServerBackup } from '@/api/transformers'; +import { Transformers, ServerBackup } from '@definitions/user'; import { ServerContext } from '@/state/server'; import { createContext, useContext } from 'react'; @@ -22,7 +21,7 @@ export default () => { const { data } = await http.get(`/api/client/servers/${uuid}/backups`, { params: { page } }); return ({ - items: (data.data || []).map(rawDataToServerBackup), + items: (data.data || []).map(Transformers.toServerBackup), pagination: getPaginationSet(data.meta.pagination), backupCount: data.meta.backup_count, }); diff --git a/resources/scripts/api/swr/getServerStartup.ts b/resources/scripts/api/swr/getServerStartup.ts index c09088735..d1ae4892a 100644 --- a/resources/scripts/api/swr/getServerStartup.ts +++ b/resources/scripts/api/swr/getServerStartup.ts @@ -1,7 +1,6 @@ import useSWR from 'swr'; import http, { FractalResponseList } from '@/api/http'; -import { rawDataToServerEggVariable } from '@/api/transformers'; -import { ServerEggVariable } from '@/api/server/types'; +import { Transformers, ServerEggVariable } from '@definitions/user'; interface Response { invocation: string; @@ -12,7 +11,7 @@ interface Response { export default (uuid: string, initialData?: Response) => useSWR([ uuid, '/startup' ], async (): Promise => { const { data } = await http.get(`/api/client/servers/${uuid}/startup`); - const variables = ((data as FractalResponseList).data || []).map(rawDataToServerEggVariable); + const variables = ((data as FractalResponseList).data || []).map(Transformers.toServerEggVariable); return { invocation: data.meta.startup_command, variables, dockerImages: data.meta.docker_images || [] }; }, { fallbackData: initialData, errorRetryCount: 3 }); diff --git a/resources/scripts/api/transformers.ts b/resources/scripts/api/transformers.ts index b036de558..21e151fad 100644 --- a/resources/scripts/api/transformers.ts +++ b/resources/scripts/api/transformers.ts @@ -1,16 +1,6 @@ import { FractalResponseData } from '@/api/http'; -import { Allocation } from '@/api/server/getServer'; import { FileObject } from '@/api/server/files/loadDirectory'; -import { ServerBackup, ServerEggVariable } from '@/api/server/types'; - -export const rawDataToServerAllocation = (data: FractalResponseData): Allocation => ({ - id: data.attributes.id, - ip: data.attributes.ip, - alias: data.attributes.ip_alias, - port: data.attributes.port, - notes: data.attributes.notes, - isDefault: data.attributes.is_default, -}); +import { Transformers } from '@definitions/user'; export const rawDataToFileObject = (data: FractalResponseData): FileObject => ({ key: `${data.attributes.is_file ? 'file' : 'dir'}_${data.attributes.name}`, @@ -55,24 +45,4 @@ export const rawDataToFileObject = (data: FractalResponseData): FileObject => ({ }, }); -export const rawDataToServerBackup = ({ attributes }: FractalResponseData): ServerBackup => ({ - uuid: attributes.uuid, - isSuccessful: attributes.is_successful, - isLocked: attributes.is_locked, - name: attributes.name, - ignoredFiles: attributes.ignored_files, - checksum: attributes.checksum, - bytes: attributes.bytes, - createdAt: new Date(attributes.created_at), - completedAt: attributes.completed_at ? new Date(attributes.completed_at) : null, -}); - -export const rawDataToServerEggVariable = ({ attributes }: FractalResponseData): ServerEggVariable => ({ - name: attributes.name, - description: attributes.description, - envVariable: attributes.env_variable, - defaultValue: attributes.default_value, - serverValue: attributes.server_value, - isEditable: attributes.is_editable, - rules: attributes.rules.split('|'), -}); +export const rawDataToServerAllocation = Transformers.toServerAllocation; diff --git a/resources/scripts/components/dashboard/DashboardContainer.tsx b/resources/scripts/components/dashboard/DashboardContainer.tsx index b96f6e93e..a6f94d0ed 100644 --- a/resources/scripts/components/dashboard/DashboardContainer.tsx +++ b/resources/scripts/components/dashboard/DashboardContainer.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react'; import { Server } from '@definitions/user'; -import getServers from '@/api/getServers'; +import { getServers } from '@/api/account'; import ServerRow from '@/components/dashboard/ServerRow'; import Spinner from '@/components/elements/Spinner'; import PageContentBlock from '@/components/elements/PageContentBlock'; diff --git a/resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx b/resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx index 1c91ef4d9..79f09c0d4 100644 --- a/resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx +++ b/resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx @@ -4,7 +4,7 @@ import { Form, Formik, FormikHelpers } from 'formik'; import Field from '@/components/elements/Field'; import * as Yup from 'yup'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; -import updateAccountPassword from '@/api/account/updateAccountPassword'; +import { updateAccountPassword } from '@/api/account'; import { httpErrorToHuman } from '@/api/http'; import { ApplicationStore } from '@/state'; import tw from 'twin.macro'; diff --git a/resources/scripts/components/dashboard/search/SearchModal.tsx b/resources/scripts/components/dashboard/search/SearchModal.tsx index 700c613e0..00c635b6e 100644 --- a/resources/scripts/components/dashboard/search/SearchModal.tsx +++ b/resources/scripts/components/dashboard/search/SearchModal.tsx @@ -6,7 +6,7 @@ import { object, string } from 'yup'; import debounce from 'debounce'; import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper'; import InputSpinner from '@/components/elements/InputSpinner'; -import getServers from '@/api/getServers'; +import { getServers } from '@/api/account'; import { Server } from '@definitions/user'; import { ApplicationStore } from '@/state'; import { Link } from 'react-router-dom'; diff --git a/resources/scripts/components/server/backups/BackupContextMenu.tsx b/resources/scripts/components/server/backups/BackupContextMenu.tsx index 1a0cf37ce..95eb3cfbd 100644 --- a/resources/scripts/components/server/backups/BackupContextMenu.tsx +++ b/resources/scripts/components/server/backups/BackupContextMenu.tsx @@ -1,19 +1,24 @@ import React, { useState } from 'react'; -import { faBoxOpen, faCloudDownloadAlt, faEllipsisH, faLock, faTrashAlt, faUnlock } from '@fortawesome/free-solid-svg-icons'; +import { + faBoxOpen, + faCloudDownloadAlt, + faEllipsisH, + faLock, + faTrashAlt, + faUnlock, +} from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import DropdownMenu, { DropdownButtonRow } from '@/components/elements/DropdownMenu'; -import getBackupDownloadUrl from '@/api/server/backups/getBackupDownloadUrl'; +import { getBackupDownloadUrl, deleteBackup, restoreServerBackup } from '@/api/server/backups'; import useFlash from '@/plugins/useFlash'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; -import deleteBackup from '@/api/server/backups/deleteBackup'; import ConfirmationModal from '@/components/elements/ConfirmationModal'; import Can from '@/components/elements/Can'; import tw from 'twin.macro'; import getServerBackups from '@/api/swr/getServerBackups'; -import { ServerBackup } from '@/api/server/types'; +import { ServerBackup } from '@definitions/user'; import { ServerContext } from '@/state/server'; import Input from '@/components/elements/Input'; -import { restoreServerBackup } from '@/api/server/backups'; import http, { httpErrorToHuman } from '@/api/http'; interface Props { diff --git a/resources/scripts/components/server/backups/BackupRow.tsx b/resources/scripts/components/server/backups/BackupRow.tsx index 8c6955f61..d75db81c9 100644 --- a/resources/scripts/components/server/backups/BackupRow.tsx +++ b/resources/scripts/components/server/backups/BackupRow.tsx @@ -10,7 +10,7 @@ import BackupContextMenu from '@/components/server/backups/BackupContextMenu'; import tw from 'twin.macro'; import GreyRowBox from '@/components/elements/GreyRowBox'; import getServerBackups from '@/api/swr/getServerBackups'; -import { ServerBackup } from '@/api/server/types'; +import { ServerBackup } from '@definitions/user'; import { SocketEvent } from '@/components/server/events'; interface Props { diff --git a/resources/scripts/components/server/backups/CreateBackupButton.tsx b/resources/scripts/components/server/backups/CreateBackupButton.tsx index 100bf6884..2155a02a0 100644 --- a/resources/scripts/components/server/backups/CreateBackupButton.tsx +++ b/resources/scripts/components/server/backups/CreateBackupButton.tsx @@ -5,7 +5,7 @@ import { boolean, object, string } from 'yup'; import Field from '@/components/elements/Field'; import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper'; import useFlash from '@/plugins/useFlash'; -import createServerBackup from '@/api/server/backups/createServerBackup'; +import { createServerBackup } from '@/api/server/backups'; import FlashMessageRender from '@/components/FlashMessageRender'; import Button from '@/components/elements/Button'; import tw from 'twin.macro'; diff --git a/resources/scripts/components/server/databases/CreateDatabaseButton.tsx b/resources/scripts/components/server/databases/CreateDatabaseButton.tsx index 1545e3d01..099f91a13 100644 --- a/resources/scripts/components/server/databases/CreateDatabaseButton.tsx +++ b/resources/scripts/components/server/databases/CreateDatabaseButton.tsx @@ -3,7 +3,7 @@ import Modal from '@/components/elements/Modal'; import { Form, Formik, FormikHelpers } from 'formik'; import Field from '@/components/elements/Field'; import { object, string } from 'yup'; -import createServerDatabase from '@/api/server/databases/createServerDatabase'; +import { createServerDatabase } from '@/api/server/databases'; import { ServerContext } from '@/state/server'; import { httpErrorToHuman } from '@/api/http'; import FlashMessageRender from '@/components/FlashMessageRender'; diff --git a/resources/scripts/components/server/databases/DatabaseRow.tsx b/resources/scripts/components/server/databases/DatabaseRow.tsx index 10ecace58..97f8e79d7 100644 --- a/resources/scripts/components/server/databases/DatabaseRow.tsx +++ b/resources/scripts/components/server/databases/DatabaseRow.tsx @@ -7,11 +7,11 @@ import Field from '@/components/elements/Field'; import { object, string } from 'yup'; import FlashMessageRender from '@/components/FlashMessageRender'; import { ServerContext } from '@/state/server'; -import deleteServerDatabase from '@/api/server/databases/deleteServerDatabase'; +import { deleteServerDatabase } from '@/api/server/databases'; import { httpErrorToHuman } from '@/api/http'; import RotatePasswordButton from '@/components/server/databases/RotatePasswordButton'; import Can from '@/components/elements/Can'; -import { ServerDatabase } from '@/api/server/databases/getServerDatabases'; +import { ServerDatabase } from '@definitions/user'; import useFlash from '@/plugins/useFlash'; import tw from 'twin.macro'; import Button from '@/components/elements/Button'; @@ -114,15 +114,25 @@ export default ({ database, className }: Props) => {

Database connection details

- + +
- +
- + +
@@ -157,7 +167,8 @@ export default ({ database, className }: Props) => {

{database.name}