Migrate users/network/database/backups to new format
This commit is contained in:
parent
e908c391ee
commit
bfd92c314d
52 changed files with 391 additions and 352 deletions
61
resources/scripts/api/account/index.ts
Normal file
61
resources/scripts/api/account/index.ts
Normal file
|
@ -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<PaginatedResult<Server>> => {
|
||||||
|
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<PanelPermissions> => {
|
||||||
|
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<void> => {
|
||||||
|
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<void> => {
|
||||||
|
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 };
|
|
@ -1,9 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (email: string, password: string): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.put('/api/client/account/email', { email, password })
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
interface Data {
|
|
||||||
current: string;
|
|
||||||
password: string;
|
|
||||||
confirmPassword: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ({ current, password, confirmPassword }: Data): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.put('/api/client/account/password', {
|
|
||||||
current_password: current,
|
|
||||||
password: password,
|
|
||||||
password_confirmation: confirmPassword,
|
|
||||||
})
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Model, UUID } from '@/api/definitions';
|
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 {
|
interface SecurityKey extends Model {
|
||||||
uuid: UUID;
|
uuid: UUID;
|
||||||
|
@ -60,3 +61,57 @@ interface Server extends Model {
|
||||||
variables: ServerEggVariable[];
|
variables: ServerEggVariable[];
|
||||||
allocations: Allocation[];
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import * as Models from './models';
|
import * as Models from './models';
|
||||||
import { FractalResponseData, FractalResponseList } from '@/api/http';
|
import { FractalResponseData, FractalResponseList } from '@/api/http';
|
||||||
import { rawDataToServerEggVariable } from '@/api/transformers';
|
|
||||||
|
|
||||||
export default class Transformers {
|
export default class Transformers {
|
||||||
static toSecurityKey ({ attributes }: FractalResponseData): Models.SecurityKey {
|
static toSecurityKey ({ attributes }: FractalResponseData): Models.SecurityKey {
|
||||||
|
@ -55,8 +54,59 @@ export default class Transformers {
|
||||||
featureLimits: { ...attributes.feature_limits },
|
featureLimits: { ...attributes.feature_limits },
|
||||||
isInstalling: attributes.status === 'installing' || attributes.status === 'install_failed',
|
isInstalling: attributes.status === 'installing' || attributes.status === 'install_failed',
|
||||||
isTransferring: attributes.is_transferring,
|
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),
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<PaginatedResult<Server>> => {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { PanelPermissions } from '@/state/permissions';
|
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (): Promise<PanelPermissions> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.get('/api/client/permissions')
|
|
||||||
.then(({ data }) => resolve(data.attributes.permissions))
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
47
resources/scripts/api/server/backups.ts
Normal file
47
resources/scripts/api/server/backups.ts
Normal file
|
@ -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<void> => {
|
||||||
|
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<ServerBackup> => {
|
||||||
|
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<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
http.delete(`/api/client/servers/${uuid}/backups/${backup}`)
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getBackupDownloadUrl = (uuid: string, backup: string): Promise<string> => {
|
||||||
|
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,
|
||||||
|
};
|
|
@ -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<ServerBackup> => {
|
|
||||||
const { data } = await http.post(`/api/client/servers/${uuid}/backups`, {
|
|
||||||
name: params.name,
|
|
||||||
ignored: params.ignored,
|
|
||||||
is_locked: params.isLocked,
|
|
||||||
});
|
|
||||||
|
|
||||||
return rawDataToServerBackup(data);
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (uuid: string, backup: string): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.delete(`/api/client/servers/${uuid}/backups/${backup}`)
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (uuid: string, backup: string): Promise<string> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.get(`/api/client/servers/${uuid}/backups/${backup}/download`)
|
|
||||||
.then(({ data }) => resolve(data.attributes.url))
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,7 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export const restoreServerBackup = async (uuid: string, backup: string, truncate?: boolean): Promise<void> => {
|
|
||||||
await http.post(`/api/client/servers/${uuid}/backups/${backup}/restore`, {
|
|
||||||
truncate,
|
|
||||||
});
|
|
||||||
};
|
|
50
resources/scripts/api/server/databases.ts
Normal file
50
resources/scripts/api/server/databases.ts
Normal file
|
@ -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<ServerDatabase> => {
|
||||||
|
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<ServerDatabase[]> => {
|
||||||
|
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<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
http.delete(`/api/client/servers/${uuid}/databases/${database}`)
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const rotateDatabasePassword = (uuid: string, database: string): Promise<ServerDatabase> => {
|
||||||
|
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,
|
||||||
|
};
|
|
@ -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<ServerDatabase> => {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (uuid: string, database: string): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.delete(`/api/client/servers/${uuid}/databases/${database}`)
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -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<ServerDatabase[]> => {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
import { rawDataToServerDatabase, ServerDatabase } from '@/api/server/databases/getServerDatabases';
|
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (uuid: string, database: string): Promise<ServerDatabase> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.post(`/api/client/servers/${uuid}/databases/${database}/rotate-password`)
|
|
||||||
.then((response) => resolve(rawDataToServerDatabase(response.data.attributes)))
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,7 +1,5 @@
|
||||||
import http from '@/api/http';
|
import http from '@/api/http';
|
||||||
import { Server, Transformers } from '@definitions/user';
|
import { Server, ServerEggVariable, Transformers } from '@definitions/user';
|
||||||
import { ServerEggVariable } from '@/api/server/types';
|
|
||||||
import { rawDataToServerEggVariable } from '@/api/transformers';
|
|
||||||
|
|
||||||
interface TokenResponse {
|
interface TokenResponse {
|
||||||
token: string;
|
token: string;
|
||||||
|
@ -55,7 +53,7 @@ const setSelectedDockerImage = async (uuid: string, image: string): Promise<void
|
||||||
const updateStartupVariable = async (uuid: string, key: string, value: string): Promise<[ ServerEggVariable, string ]> => {
|
const updateStartupVariable = async (uuid: string, key: string, value: string): Promise<[ ServerEggVariable, string ]> => {
|
||||||
const { data } = await http.put(`/api/client/servers/${uuid}/startup/variable`, { key, value });
|
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<ServerStats> => {
|
const getServerResourceUsage = async (server: string): Promise<ServerStats> => {
|
||||||
|
|
30
resources/scripts/api/server/network.ts
Normal file
30
resources/scripts/api/server/network.ts
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import http from '@/api/http';
|
||||||
|
import { Transformers, Allocation } from '@definitions/user';
|
||||||
|
|
||||||
|
const createServerAllocation = async (uuid: string): Promise<Allocation> => {
|
||||||
|
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`);
|
||||||
|
|
||||||
|
return Transformers.toServerAllocation(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteServerAllocation = async (uuid: string, id: number): Promise<Allocation> =>
|
||||||
|
await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`);
|
||||||
|
|
||||||
|
const setPrimaryServerAllocation = async (uuid: string, id: number): Promise<Allocation> => {
|
||||||
|
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<Allocation> => {
|
||||||
|
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes });
|
||||||
|
|
||||||
|
return Transformers.toServerAllocation(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
createServerAllocation,
|
||||||
|
deleteServerAllocation,
|
||||||
|
setPrimaryServerAllocation,
|
||||||
|
setServerAllocationNotes,
|
||||||
|
};
|
|
@ -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<Allocation> => {
|
|
||||||
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations`);
|
|
||||||
|
|
||||||
return rawDataToServerAllocation(data);
|
|
||||||
};
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { Allocation } from '@/api/server/getServer';
|
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default async (uuid: string, id: number): Promise<Allocation> => await http.delete(`/api/client/servers/${uuid}/network/allocations/${id}`);
|
|
|
@ -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<Allocation> => {
|
|
||||||
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}/primary`);
|
|
||||||
|
|
||||||
return rawDataToServerAllocation(data);
|
|
||||||
};
|
|
|
@ -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<Allocation> => {
|
|
||||||
const { data } = await http.post(`/api/client/servers/${uuid}/network/allocations/${id}`, { notes });
|
|
||||||
|
|
||||||
return rawDataToServerAllocation(data);
|
|
||||||
};
|
|
23
resources/scripts/api/server/types.d.ts
vendored
23
resources/scripts/api/server/types.d.ts
vendored
|
@ -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[];
|
|
||||||
}
|
|
39
resources/scripts/api/server/users.ts
Normal file
39
resources/scripts/api/server/users.ts
Normal file
|
@ -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<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
http.delete(`/api/client/servers/${uuid}/users/${userId}`)
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getServerSubusers = (uuid: string): Promise<Subuser[]> => {
|
||||||
|
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<Subuser> => {
|
||||||
|
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,
|
||||||
|
};
|
|
@ -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<Subuser> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.post(`/api/client/servers/${uuid}/users${subuser ? `/${subuser.uuid}` : ''}`, {
|
|
||||||
...params,
|
|
||||||
})
|
|
||||||
.then(data => resolve(rawDataToServerSubuser(data.data)))
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,9 +0,0 @@
|
||||||
import http from '@/api/http';
|
|
||||||
|
|
||||||
export default (uuid: string, userId: string): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.delete(`/api/client/servers/${uuid}/users/${userId}`)
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -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<Subuser[]> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
http.get(`/api/client/servers/${uuid}/users`)
|
|
||||||
.then(({ data }) => resolve((data.data || []).map(rawDataToServerSubuser)))
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import http from '@/api/http';
|
import http from '@/api/http';
|
||||||
import { rawDataToServerAllocation } from '@/api/transformers';
|
import { Allocation, Transformers } from '@definitions/user';
|
||||||
import { Allocation } from '@/api/server/getServer';
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
|
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
|
||||||
|
@ -10,6 +9,6 @@ export default () => {
|
||||||
return useSWR<Allocation[]>([ 'server:allocations', uuid ], async () => {
|
return useSWR<Allocation[]>([ 'server:allocations', uuid ], async () => {
|
||||||
const { data } = await http.get(`/api/client/servers/${uuid}/network/allocations`);
|
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 });
|
}, { revalidateOnFocus: false, revalidateOnMount: false });
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import http, { getPaginationSet, PaginatedResult } from '@/api/http';
|
import http, { getPaginationSet, PaginatedResult } from '@/api/http';
|
||||||
import { ServerBackup } from '@/api/server/types';
|
import { Transformers, ServerBackup } from '@definitions/user';
|
||||||
import { rawDataToServerBackup } from '@/api/transformers';
|
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import { createContext, useContext } from 'react';
|
import { createContext, useContext } from 'react';
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ export default () => {
|
||||||
const { data } = await http.get(`/api/client/servers/${uuid}/backups`, { params: { page } });
|
const { data } = await http.get(`/api/client/servers/${uuid}/backups`, { params: { page } });
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
items: (data.data || []).map(rawDataToServerBackup),
|
items: (data.data || []).map(Transformers.toServerBackup),
|
||||||
pagination: getPaginationSet(data.meta.pagination),
|
pagination: getPaginationSet(data.meta.pagination),
|
||||||
backupCount: data.meta.backup_count,
|
backupCount: data.meta.backup_count,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
import http, { FractalResponseList } from '@/api/http';
|
import http, { FractalResponseList } from '@/api/http';
|
||||||
import { rawDataToServerEggVariable } from '@/api/transformers';
|
import { Transformers, ServerEggVariable } from '@definitions/user';
|
||||||
import { ServerEggVariable } from '@/api/server/types';
|
|
||||||
|
|
||||||
interface Response {
|
interface Response {
|
||||||
invocation: string;
|
invocation: string;
|
||||||
|
@ -12,7 +11,7 @@ interface Response {
|
||||||
export default (uuid: string, initialData?: Response) => useSWR([ uuid, '/startup' ], async (): Promise<Response> => {
|
export default (uuid: string, initialData?: Response) => useSWR([ uuid, '/startup' ], async (): Promise<Response> => {
|
||||||
const { data } = await http.get(`/api/client/servers/${uuid}/startup`);
|
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 || [] };
|
return { invocation: data.meta.startup_command, variables, dockerImages: data.meta.docker_images || [] };
|
||||||
}, { fallbackData: initialData, errorRetryCount: 3 });
|
}, { fallbackData: initialData, errorRetryCount: 3 });
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
import { FractalResponseData } from '@/api/http';
|
import { FractalResponseData } from '@/api/http';
|
||||||
import { Allocation } from '@/api/server/getServer';
|
|
||||||
import { FileObject } from '@/api/server/files/loadDirectory';
|
import { FileObject } from '@/api/server/files/loadDirectory';
|
||||||
import { ServerBackup, ServerEggVariable } from '@/api/server/types';
|
import { Transformers } from '@definitions/user';
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const rawDataToFileObject = (data: FractalResponseData): FileObject => ({
|
export const rawDataToFileObject = (data: FractalResponseData): FileObject => ({
|
||||||
key: `${data.attributes.is_file ? 'file' : 'dir'}_${data.attributes.name}`,
|
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 => ({
|
export const rawDataToServerAllocation = Transformers.toServerAllocation;
|
||||||
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('|'),
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Server } from '@definitions/user';
|
import { Server } from '@definitions/user';
|
||||||
import getServers from '@/api/getServers';
|
import { getServers } from '@/api/account';
|
||||||
import ServerRow from '@/components/dashboard/ServerRow';
|
import ServerRow from '@/components/dashboard/ServerRow';
|
||||||
import Spinner from '@/components/elements/Spinner';
|
import Spinner from '@/components/elements/Spinner';
|
||||||
import PageContentBlock from '@/components/elements/PageContentBlock';
|
import PageContentBlock from '@/components/elements/PageContentBlock';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Form, Formik, FormikHelpers } from 'formik';
|
||||||
import Field from '@/components/elements/Field';
|
import Field from '@/components/elements/Field';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||||
import updateAccountPassword from '@/api/account/updateAccountPassword';
|
import { updateAccountPassword } from '@/api/account';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import { ApplicationStore } from '@/state';
|
import { ApplicationStore } from '@/state';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { object, string } from 'yup';
|
||||||
import debounce from 'debounce';
|
import debounce from 'debounce';
|
||||||
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
||||||
import InputSpinner from '@/components/elements/InputSpinner';
|
import InputSpinner from '@/components/elements/InputSpinner';
|
||||||
import getServers from '@/api/getServers';
|
import { getServers } from '@/api/account';
|
||||||
import { Server } from '@definitions/user';
|
import { Server } from '@definitions/user';
|
||||||
import { ApplicationStore } from '@/state';
|
import { ApplicationStore } from '@/state';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
import React, { useState } from 'react';
|
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 { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import DropdownMenu, { DropdownButtonRow } from '@/components/elements/DropdownMenu';
|
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 useFlash from '@/plugins/useFlash';
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||||
import deleteBackup from '@/api/server/backups/deleteBackup';
|
|
||||||
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import getServerBackups from '@/api/swr/getServerBackups';
|
import getServerBackups from '@/api/swr/getServerBackups';
|
||||||
import { ServerBackup } from '@/api/server/types';
|
import { ServerBackup } from '@definitions/user';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import Input from '@/components/elements/Input';
|
import Input from '@/components/elements/Input';
|
||||||
import { restoreServerBackup } from '@/api/server/backups';
|
|
||||||
import http, { httpErrorToHuman } from '@/api/http';
|
import http, { httpErrorToHuman } from '@/api/http';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import BackupContextMenu from '@/components/server/backups/BackupContextMenu';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import GreyRowBox from '@/components/elements/GreyRowBox';
|
import GreyRowBox from '@/components/elements/GreyRowBox';
|
||||||
import getServerBackups from '@/api/swr/getServerBackups';
|
import getServerBackups from '@/api/swr/getServerBackups';
|
||||||
import { ServerBackup } from '@/api/server/types';
|
import { ServerBackup } from '@definitions/user';
|
||||||
import { SocketEvent } from '@/components/server/events';
|
import { SocketEvent } from '@/components/server/events';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { boolean, object, string } from 'yup';
|
||||||
import Field from '@/components/elements/Field';
|
import Field from '@/components/elements/Field';
|
||||||
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
import createServerBackup from '@/api/server/backups/createServerBackup';
|
import { createServerBackup } from '@/api/server/backups';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Modal from '@/components/elements/Modal';
|
||||||
import { Form, Formik, FormikHelpers } from 'formik';
|
import { Form, Formik, FormikHelpers } from 'formik';
|
||||||
import Field from '@/components/elements/Field';
|
import Field from '@/components/elements/Field';
|
||||||
import { object, string } from 'yup';
|
import { object, string } from 'yup';
|
||||||
import createServerDatabase from '@/api/server/databases/createServerDatabase';
|
import { createServerDatabase } from '@/api/server/databases';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
|
|
|
@ -7,11 +7,11 @@ import Field from '@/components/elements/Field';
|
||||||
import { object, string } from 'yup';
|
import { object, string } from 'yup';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import deleteServerDatabase from '@/api/server/databases/deleteServerDatabase';
|
import { deleteServerDatabase } from '@/api/server/databases';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import RotatePasswordButton from '@/components/server/databases/RotatePasswordButton';
|
import RotatePasswordButton from '@/components/server/databases/RotatePasswordButton';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
import { ServerDatabase } from '@/api/server/databases/getServerDatabases';
|
import { ServerDatabase } from '@definitions/user';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
|
@ -114,7 +114,12 @@ export default ({ database, className }: Props) => {
|
||||||
<h3 css={tw`mb-6 text-2xl`}>Database connection details</h3>
|
<h3 css={tw`mb-6 text-2xl`}>Database connection details</h3>
|
||||||
<div>
|
<div>
|
||||||
<Label>Endpoint</Label>
|
<Label>Endpoint</Label>
|
||||||
<CopyOnClick text={database.connectionString}><Input type={'text'} readOnly value={database.connectionString} /></CopyOnClick>
|
<CopyOnClick text={database.connectionString}><Input
|
||||||
|
type={'text'}
|
||||||
|
readOnly
|
||||||
|
value={database.connectionString}
|
||||||
|
/>
|
||||||
|
</CopyOnClick>
|
||||||
</div>
|
</div>
|
||||||
<div css={tw`mt-6`}>
|
<div css={tw`mt-6`}>
|
||||||
<Label>Connections from</Label>
|
<Label>Connections from</Label>
|
||||||
|
@ -122,7 +127,12 @@ export default ({ database, className }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
<div css={tw`mt-6`}>
|
<div css={tw`mt-6`}>
|
||||||
<Label>Username</Label>
|
<Label>Username</Label>
|
||||||
<CopyOnClick text={database.username}><Input type={'text'} readOnly value={database.username} /></CopyOnClick>
|
<CopyOnClick text={database.username}><Input
|
||||||
|
type={'text'}
|
||||||
|
readOnly
|
||||||
|
value={database.username}
|
||||||
|
/>
|
||||||
|
</CopyOnClick>
|
||||||
</div>
|
</div>
|
||||||
<Can action={'database.view_password'}>
|
<Can action={'database.view_password'}>
|
||||||
<div css={tw`mt-6`}>
|
<div css={tw`mt-6`}>
|
||||||
|
@ -157,7 +167,8 @@ export default ({ database, className }: Props) => {
|
||||||
<CopyOnClick text={database.name}><p css={tw`text-lg`}>{database.name}</p></CopyOnClick>
|
<CopyOnClick text={database.name}><p css={tw`text-lg`}>{database.name}</p></CopyOnClick>
|
||||||
</div>
|
</div>
|
||||||
<div css={tw`ml-8 text-center hidden md:block`}>
|
<div css={tw`ml-8 text-center hidden md:block`}>
|
||||||
<CopyOnClick text={database.connectionString}><p css={tw`text-sm`}>{database.connectionString}</p></CopyOnClick>
|
<CopyOnClick text={database.connectionString}><p css={tw`text-sm`}>{database.connectionString}</p>
|
||||||
|
</CopyOnClick>
|
||||||
<p css={tw`mt-1 text-2xs text-neutral-500 uppercase select-none`}>Endpoint</p>
|
<p css={tw`mt-1 text-2xs text-neutral-500 uppercase select-none`}>Endpoint</p>
|
||||||
</div>
|
</div>
|
||||||
<div css={tw`ml-8 text-center hidden md:block`}>
|
<div css={tw`ml-8 text-center hidden md:block`}>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import getServerDatabases from '@/api/server/databases/getServerDatabases';
|
import { getServerDatabases } from '@/api/server/databases';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import rotateDatabasePassword from '@/api/server/databases/rotateDatabasePassword';
|
import { rotateDatabasePassword } from '@/api/server/databases';
|
||||||
import { Actions, useStoreActions } from 'easy-peasy';
|
import { Actions, useStoreActions } from 'easy-peasy';
|
||||||
import { ApplicationStore } from '@/state';
|
import { ApplicationStore } from '@/state';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import { ServerDatabase } from '@/api/server/databases/getServerDatabases';
|
import { ServerDatabase } from '@definitions/user';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
|
|
|
@ -10,12 +10,11 @@ import Button from '@/components/elements/Button';
|
||||||
import GreyRowBox from '@/components/elements/GreyRowBox';
|
import GreyRowBox from '@/components/elements/GreyRowBox';
|
||||||
import { Allocation } from '@/api/server/getServer';
|
import { Allocation } from '@/api/server/getServer';
|
||||||
import { debounce } from 'debounce';
|
import { debounce } from 'debounce';
|
||||||
import setServerAllocationNotes from '@/api/server/network/setServerAllocationNotes';
|
import { setServerAllocationNotes, setPrimaryServerAllocation } from '@/api/server/network';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import CopyOnClick from '@/components/elements/CopyOnClick';
|
import CopyOnClick from '@/components/elements/CopyOnClick';
|
||||||
import DeleteAllocationButton from '@/components/server/network/DeleteAllocationButton';
|
import DeleteAllocationButton from '@/components/server/network/DeleteAllocationButton';
|
||||||
import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation';
|
|
||||||
import getServerAllocations from '@/api/swr/getServerAllocations';
|
import getServerAllocations from '@/api/swr/getServerAllocations';
|
||||||
import { formatIp } from '@/helpers';
|
import { formatIp } from '@/helpers';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import tw from 'twin.macro';
|
||||||
import Icon from '@/components/elements/Icon';
|
import Icon from '@/components/elements/Icon';
|
||||||
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import deleteServerAllocation from '@/api/server/network/deleteServerAllocation';
|
import { deleteServerAllocation } from '@/api/server/network';
|
||||||
import getServerAllocations from '@/api/swr/getServerAllocations';
|
import getServerAllocations from '@/api/swr/getServerAllocations';
|
||||||
import useFlash from '@/plugins/useFlash';
|
import useFlash from '@/plugins/useFlash';
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import ServerContentBlock from '@/components/elements/ServerContentBlock';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import AllocationRow from '@/components/server/network/AllocationRow';
|
import AllocationRow from '@/components/server/network/AllocationRow';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
import createServerAllocation from '@/api/server/network/createServerAllocation';
|
import { createServerAllocation } from '@/api/server/network';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { memo, useState } from 'react';
|
import React, { memo, useState } from 'react';
|
||||||
import { ServerEggVariable } from '@/api/server/types';
|
import { ServerEggVariable } from '@definitions/user';
|
||||||
import TitledGreyBox from '@/components/elements/TitledGreyBox';
|
import TitledGreyBox from '@/components/elements/TitledGreyBox';
|
||||||
import { usePermissions } from '@/plugins/usePermissions';
|
import { usePermissions } from '@/plugins/usePermissions';
|
||||||
import InputSpinner from '@/components/elements/InputSpinner';
|
import InputSpinner from '@/components/elements/InputSpinner';
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { array, object, string } from 'yup';
|
||||||
import Field from '@/components/elements/Field';
|
import Field from '@/components/elements/Field';
|
||||||
import { Actions, useStoreActions, useStoreState } from 'easy-peasy';
|
import { Actions, useStoreActions, useStoreState } from 'easy-peasy';
|
||||||
import { ApplicationStore } from '@/state';
|
import { ApplicationStore } from '@/state';
|
||||||
import createOrUpdateSubuser from '@/api/server/users/createOrUpdateSubuser';
|
import { createOrUpdateSubuser } from '@/api/server/users';
|
||||||
import { ServerContext } from '@/state/server';
|
import { ServerContext } from '@/state/server';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { ServerContext } from '@/state/server';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
|
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { Subuser } from '@/state/server/subusers';
|
import { Subuser } from '@/state/server/subusers';
|
||||||
import deleteSubuser from '@/api/server/users/deleteSubuser';
|
import { deleteSubuser } from '@/api/server/users';
|
||||||
import { Actions, useStoreActions } from 'easy-peasy';
|
import { Actions, useStoreActions } from 'easy-peasy';
|
||||||
import { ApplicationStore } from '@/state';
|
import { ApplicationStore } from '@/state';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Spinner from '@/components/elements/Spinner';
|
||||||
import AddSubuserButton from '@/components/server/users/AddSubuserButton';
|
import AddSubuserButton from '@/components/server/users/AddSubuserButton';
|
||||||
import UserRow from '@/components/server/users/UserRow';
|
import UserRow from '@/components/server/users/UserRow';
|
||||||
import FlashMessageRender from '@/components/FlashMessageRender';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
import getServerSubusers from '@/api/server/users/getServerSubusers';
|
import { getServerSubusers } from '@/api/server/users';
|
||||||
import { httpErrorToHuman } from '@/api/http';
|
import { httpErrorToHuman } from '@/api/http';
|
||||||
import Can from '@/components/elements/Can';
|
import Can from '@/components/elements/Can';
|
||||||
import ServerContentBlock from '@/components/elements/ServerContentBlock';
|
import ServerContentBlock from '@/components/elements/ServerContentBlock';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { action, Action, thunk, Thunk } from 'easy-peasy';
|
import { action, Action, thunk, Thunk } from 'easy-peasy';
|
||||||
import getSystemPermissions from '@/api/getSystemPermissions';
|
import { getSystemPermissions } from '@/api/account';
|
||||||
|
|
||||||
export interface PanelPermissions {
|
export interface PanelPermissions {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { action, Action } from 'easy-peasy';
|
import { action, Action } from 'easy-peasy';
|
||||||
import { ServerDatabase } from '@/api/server/databases/getServerDatabases';
|
import { ServerDatabase } from '@definitions/user';
|
||||||
|
|
||||||
export interface ServerDatabaseStore {
|
export interface ServerDatabaseStore {
|
||||||
data: ServerDatabase[];
|
data: ServerDatabase[];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Action, action, Thunk, thunk } from 'easy-peasy';
|
import { Action, action, Thunk, thunk } from 'easy-peasy';
|
||||||
import updateAccountEmail from '@/api/account/updateAccountEmail';
|
import { updateAccountEmail } from '@/api/account';
|
||||||
|
|
||||||
export interface UserData {
|
export interface UserData {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
|
|
Loading…
Reference in a new issue