mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-02 05:23:14 +00:00
Merge branch 'next/minor' of github.com:Start9Labs/start-os into next/major
This commit is contained in:
8
web/projects/ui/src/app/services/api/api-icons.ts
Normal file
8
web/projects/ui/src/app/services/api/api-icons.ts
Normal file
File diff suppressed because one or more lines are too long
1491
web/projects/ui/src/app/services/api/api.fixures.ts
Normal file
1491
web/projects/ui/src/app/services/api/api.fixures.ts
Normal file
File diff suppressed because it is too large
Load Diff
605
web/projects/ui/src/app/services/api/api.types.ts
Normal file
605
web/projects/ui/src/app/services/api/api.types.ts
Normal file
@@ -0,0 +1,605 @@
|
||||
import { Dump, Revision } from 'patch-db-client'
|
||||
import { MarketplacePkg, StoreInfo, Manifest } from '@start9labs/marketplace'
|
||||
import { InputSpec } from '@start9labs/start-sdk/lib/config/configTypes'
|
||||
import {
|
||||
DataModel,
|
||||
HealthCheckResult,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { StartOSDiskInfo, LogsRes, ServerLogsReq } from '@start9labs/shared'
|
||||
import { customSmtp } from '@start9labs/start-sdk/lib/config/configConstants'
|
||||
|
||||
export module RR {
|
||||
// DB
|
||||
|
||||
export type GetRevisionsRes = Revision[] | Dump<DataModel>
|
||||
|
||||
export type GetDumpRes = Dump<DataModel>
|
||||
|
||||
export type SetDBValueReq<T> = { pointer: string; value: T } // db.put.ui
|
||||
export type SetDBValueRes = null
|
||||
|
||||
// auth
|
||||
|
||||
export type LoginReq = {
|
||||
password: string
|
||||
metadata: SessionMetadata
|
||||
} // auth.login - unauthed
|
||||
export type loginRes = null
|
||||
|
||||
export type LogoutReq = {} // auth.logout
|
||||
export type LogoutRes = null
|
||||
|
||||
export type ResetPasswordReq = {
|
||||
'old-password': string
|
||||
'new-password': string
|
||||
} // auth.reset-password
|
||||
export type ResetPasswordRes = null
|
||||
|
||||
// server
|
||||
|
||||
export type EchoReq = { message: string; timeout?: number } // server.echo
|
||||
export type EchoRes = string
|
||||
|
||||
export type GetSystemTimeReq = {} // server.time
|
||||
export type GetSystemTimeRes = {
|
||||
now: string
|
||||
uptime: number // seconds
|
||||
}
|
||||
|
||||
export type GetServerLogsReq = ServerLogsReq // server.logs & server.kernel-logs
|
||||
export type GetServerLogsRes = LogsRes
|
||||
|
||||
export type FollowServerLogsReq = { limit?: number } // server.logs.follow & server.kernel-logs.follow
|
||||
export type FollowServerLogsRes = {
|
||||
'start-cursor': string
|
||||
guid: string
|
||||
}
|
||||
|
||||
export type GetServerMetricsReq = {} // server.metrics
|
||||
export type GetServerMetricsRes = {
|
||||
guid: string
|
||||
metrics: Metrics
|
||||
}
|
||||
|
||||
export type UpdateServerReq = { 'marketplace-url': string } // server.update
|
||||
export type UpdateServerRes = 'updating' | 'no-updates'
|
||||
|
||||
export type RestartServerReq = {} // server.restart
|
||||
export type RestartServerRes = null
|
||||
|
||||
export type ShutdownServerReq = {} // server.shutdown
|
||||
export type ShutdownServerRes = null
|
||||
|
||||
export type SystemRebuildReq = {} // server.rebuild
|
||||
export type SystemRebuildRes = null
|
||||
|
||||
export type ResetTorReq = {
|
||||
'wipe-state': boolean
|
||||
reason: string
|
||||
} // net.tor.reset
|
||||
export type ResetTorRes = null
|
||||
|
||||
export type ToggleZramReq = {
|
||||
enable: boolean
|
||||
} // server.experimental.zram
|
||||
export type ToggleZramRes = null
|
||||
|
||||
// sessions
|
||||
|
||||
export type GetSessionsReq = {} // sessions.list
|
||||
export type GetSessionsRes = {
|
||||
current: string
|
||||
sessions: { [hash: string]: Session }
|
||||
}
|
||||
|
||||
export type KillSessionsReq = { ids: string[] } // sessions.kill
|
||||
export type KillSessionsRes = null
|
||||
|
||||
// notification
|
||||
|
||||
export type GetNotificationsReq = {
|
||||
before?: number
|
||||
limit?: number
|
||||
} // notification.list
|
||||
export type GetNotificationsRes = ServerNotification<number>[]
|
||||
|
||||
export type DeleteNotificationReq = { id: number } // notification.delete
|
||||
export type DeleteNotificationRes = null
|
||||
|
||||
export type DeleteAllNotificationsReq = { before: number } // notification.delete-before
|
||||
export type DeleteAllNotificationsRes = null
|
||||
|
||||
// wifi
|
||||
|
||||
export type GetWifiReq = {}
|
||||
export type GetWifiRes = {
|
||||
ssids: {
|
||||
[ssid: string]: number
|
||||
}
|
||||
connected: string | null
|
||||
country: string | null
|
||||
ethernet: boolean
|
||||
'available-wifi': AvailableWifi[]
|
||||
}
|
||||
|
||||
export type AddWifiReq = {
|
||||
// wifi.add
|
||||
ssid: string
|
||||
password: string
|
||||
priority: number
|
||||
connect: boolean
|
||||
}
|
||||
export type AddWifiRes = null
|
||||
|
||||
export type EnableWifiReq = { enable: boolean } // wifi.enable
|
||||
export type EnableWifiRes = null
|
||||
|
||||
export type ConnectWifiReq = { ssid: string } // wifi.connect
|
||||
export type ConnectWifiRes = null
|
||||
|
||||
export type DeleteWifiReq = { ssid: string } // wifi.delete
|
||||
export type DeleteWifiRes = null
|
||||
|
||||
// email
|
||||
|
||||
export type ConfigureEmailReq = typeof customSmtp.validator._TYPE // email.configure
|
||||
export type ConfigureEmailRes = null
|
||||
|
||||
export type TestEmailReq = ConfigureEmailReq & { to: string } // email.test
|
||||
export type TestEmailRes = null
|
||||
|
||||
// ssh
|
||||
|
||||
export type GetSSHKeysReq = {} // ssh.list
|
||||
export type GetSSHKeysRes = SSHKey[]
|
||||
|
||||
export type AddSSHKeyReq = { key: string } // ssh.add
|
||||
export type AddSSHKeyRes = SSHKey
|
||||
|
||||
export type DeleteSSHKeyReq = { fingerprint: string } // ssh.delete
|
||||
export type DeleteSSHKeyRes = null
|
||||
|
||||
// backup
|
||||
|
||||
export type GetBackupTargetsReq = {} // backup.target.list
|
||||
export type GetBackupTargetsRes = {
|
||||
'unknown-disks': UnknownDisk[]
|
||||
saved: BackupTarget[]
|
||||
}
|
||||
|
||||
export type AddCifsBackupTargetReq = {
|
||||
name: string
|
||||
path: string
|
||||
hostname: string
|
||||
username: string
|
||||
password?: string
|
||||
} // backup.target.cifs.add
|
||||
export type AddCloudBackupTargetReq = {
|
||||
name: string
|
||||
path: string
|
||||
provider: CloudProvider
|
||||
[params: string]: any
|
||||
} // backup.target.cloud.add
|
||||
export type AddDiskBackupTargetReq = {
|
||||
logicalname: string
|
||||
name: string
|
||||
path: string
|
||||
} // backup.target.disk.add
|
||||
export type AddBackupTargetRes = BackupTarget
|
||||
|
||||
export type UpdateCifsBackupTargetReq = AddCifsBackupTargetReq & {
|
||||
id: string
|
||||
} // backup.target.cifs.update
|
||||
export type UpdateCloudBackupTargetReq = AddCloudBackupTargetReq & {
|
||||
id: string
|
||||
} // backup.target.cloud.update
|
||||
export type UpdateDiskBackupTargetReq = Omit<
|
||||
AddDiskBackupTargetReq,
|
||||
'logicalname'
|
||||
> & {
|
||||
id: string
|
||||
} // backup.target.disk.update
|
||||
export type UpdateBackupTargetRes = AddBackupTargetRes
|
||||
|
||||
export type RemoveBackupTargetReq = { id: string } // backup.target.remove
|
||||
export type RemoveBackupTargetRes = null
|
||||
|
||||
export type GetBackupJobsReq = {} // backup.job.list
|
||||
export type GetBackupJobsRes = BackupJob[]
|
||||
|
||||
export type CreateBackupJobReq = {
|
||||
name: string
|
||||
'target-id': string
|
||||
cron: string
|
||||
'package-ids': string[]
|
||||
now: boolean
|
||||
} // backup.job.create
|
||||
export type CreateBackupJobRes = BackupJob
|
||||
|
||||
export type UpdateBackupJobReq = Omit<CreateBackupJobReq, 'now'> & {
|
||||
id: string
|
||||
} // backup.job.update
|
||||
export type UpdateBackupJobRes = CreateBackupJobRes
|
||||
|
||||
export type DeleteBackupJobReq = { id: string } // backup.job.delete
|
||||
export type DeleteBackupJobRes = null
|
||||
|
||||
export type GetBackupRunsReq = {} // backup.runs
|
||||
export type GetBackupRunsRes = BackupRun[]
|
||||
|
||||
export type DeleteBackupRunsReq = { ids: string[] } // backup.runs.delete
|
||||
export type DeleteBackupRunsRes = null
|
||||
|
||||
export type GetBackupInfoReq = { 'target-id': string; password: string } // backup.target.info
|
||||
export type GetBackupInfoRes = BackupInfo
|
||||
|
||||
export type CreateBackupReq = { 'target-id': string; 'package-ids': string[] } // backup.create
|
||||
export type CreateBackupRes = null
|
||||
|
||||
// package
|
||||
|
||||
export type GetPackageCredentialsReq = { id: string } // package.credentials
|
||||
export type GetPackageCredentialsRes = Record<string, string>
|
||||
|
||||
export type GetPackageLogsReq = ServerLogsReq & { id: string } // package.logs
|
||||
export type GetPackageLogsRes = LogsRes
|
||||
|
||||
export type FollowPackageLogsReq = FollowServerLogsReq & { id: string } // package.logs.follow
|
||||
export type FollowPackageLogsRes = FollowServerLogsRes
|
||||
|
||||
export type InstallPackageReq = {
|
||||
id: string
|
||||
'version-spec'?: string
|
||||
'version-priority'?: 'min' | 'max'
|
||||
'marketplace-url': string
|
||||
} // package.install
|
||||
export type InstallPackageRes = null
|
||||
|
||||
export type GetPackageConfigReq = { id: string } // package.config.get
|
||||
export type GetPackageConfigRes = { spec: InputSpec; config: object }
|
||||
|
||||
export type DrySetPackageConfigReq = { id: string; config: object } // package.config.set.dry
|
||||
export type DrySetPackageConfigRes = Breakages
|
||||
|
||||
export type SetPackageConfigReq = DrySetPackageConfigReq // package.config.set
|
||||
export type SetPackageConfigRes = null
|
||||
|
||||
export type RestorePackagesReq = {
|
||||
// package.backup.restore
|
||||
ids: string[]
|
||||
'target-id': string
|
||||
password: string
|
||||
}
|
||||
export type RestorePackagesRes = null
|
||||
|
||||
export type ExecutePackageActionReq = {
|
||||
id: string
|
||||
'action-id': string
|
||||
input?: object
|
||||
} // package.action
|
||||
export type ExecutePackageActionRes = ActionResponse
|
||||
|
||||
export type StartPackageReq = { id: string } // package.start
|
||||
export type StartPackageRes = null
|
||||
|
||||
export type RestartPackageReq = { id: string } // package.restart
|
||||
export type RestartPackageRes = null
|
||||
|
||||
export type StopPackageReq = { id: string } // package.stop
|
||||
export type StopPackageRes = null
|
||||
|
||||
export type UninstallPackageReq = { id: string } // package.uninstall
|
||||
export type UninstallPackageRes = null
|
||||
|
||||
export type DryConfigureDependencyReq = {
|
||||
'dependency-id': string
|
||||
'dependent-id': string
|
||||
} // package.dependency.configure.dry
|
||||
export type DryConfigureDependencyRes = {
|
||||
'old-config': object
|
||||
'new-config': object
|
||||
spec: InputSpec
|
||||
}
|
||||
|
||||
export type SideloadPackageReq = {
|
||||
manifest: Manifest
|
||||
icon: string // base64
|
||||
size: number // bytes
|
||||
}
|
||||
export type SideloadPacakgeRes = string //guid
|
||||
|
||||
// marketplace
|
||||
|
||||
export type GetMarketplaceInfoReq = { 'server-id': string }
|
||||
export type GetMarketplaceInfoRes = StoreInfo
|
||||
|
||||
export type GetMarketplaceEosReq = { 'server-id': string }
|
||||
export type GetMarketplaceEosRes = MarketplaceEOS
|
||||
|
||||
export type GetMarketplacePackagesReq = {
|
||||
ids?: { id: string; version: string }[]
|
||||
// iff !ids
|
||||
category?: string
|
||||
query?: string
|
||||
page?: number
|
||||
'per-page'?: number
|
||||
}
|
||||
export type GetMarketplacePackagesRes = MarketplacePkg[]
|
||||
|
||||
export type GetReleaseNotesReq = { id: string }
|
||||
export type GetReleaseNotesRes = { [version: string]: string }
|
||||
}
|
||||
|
||||
export interface MarketplaceEOS {
|
||||
version: string
|
||||
headline: string
|
||||
'release-notes': { [version: string]: string }
|
||||
}
|
||||
|
||||
export interface Breakages {
|
||||
[id: string]: TaggedDependencyError
|
||||
}
|
||||
|
||||
export interface TaggedDependencyError {
|
||||
dependency: string
|
||||
error: DependencyError
|
||||
}
|
||||
|
||||
export interface ActionResponse {
|
||||
message: string
|
||||
value: string | null
|
||||
copyable: boolean
|
||||
qr: boolean
|
||||
}
|
||||
|
||||
interface MetricData {
|
||||
value: string
|
||||
unit: string
|
||||
}
|
||||
|
||||
export interface Metrics {
|
||||
general: {
|
||||
temperature: MetricData | null
|
||||
}
|
||||
memory: {
|
||||
total: MetricData
|
||||
'percentage-used': MetricData
|
||||
used: MetricData
|
||||
available: MetricData
|
||||
'zram-total': MetricData
|
||||
'zram-used': MetricData
|
||||
'zram-available': MetricData
|
||||
}
|
||||
cpu: {
|
||||
'percentage-used': MetricData
|
||||
idle: MetricData
|
||||
'user-space': MetricData
|
||||
'kernel-space': MetricData
|
||||
wait: MetricData
|
||||
}
|
||||
disk: {
|
||||
capacity: MetricData
|
||||
'percentage-used': MetricData
|
||||
used: MetricData
|
||||
available: MetricData
|
||||
}
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
'last-active': string
|
||||
'user-agent': string
|
||||
metadata: SessionMetadata
|
||||
}
|
||||
|
||||
export interface SessionMetadata {
|
||||
platforms: PlatformType[]
|
||||
}
|
||||
|
||||
export type PlatformType =
|
||||
| 'cli'
|
||||
| 'ios'
|
||||
| 'ipad'
|
||||
| 'iphone'
|
||||
| 'android'
|
||||
| 'phablet'
|
||||
| 'tablet'
|
||||
| 'cordova'
|
||||
| 'capacitor'
|
||||
| 'electron'
|
||||
| 'pwa'
|
||||
| 'mobile'
|
||||
| 'mobileweb'
|
||||
| 'desktop'
|
||||
| 'hybrid'
|
||||
|
||||
export type RemoteBackupTarget = CifsBackupTarget | CloudBackupTarget
|
||||
export type BackupTarget = RemoteBackupTarget | DiskBackupTarget
|
||||
|
||||
export type BackupTargetType = 'disk' | 'cifs' | 'cloud'
|
||||
|
||||
export interface UnknownDisk {
|
||||
logicalname: string
|
||||
vendor: string | null
|
||||
model: string | null
|
||||
label: string | null
|
||||
capacity: number
|
||||
used: number | null
|
||||
}
|
||||
|
||||
export interface BaseBackupTarget {
|
||||
id: string
|
||||
type: BackupTargetType
|
||||
name: string
|
||||
mountable: boolean
|
||||
path: string
|
||||
'embassy-os': StartOSDiskInfo | null
|
||||
}
|
||||
|
||||
export interface DiskBackupTarget extends UnknownDisk, BaseBackupTarget {
|
||||
type: 'disk'
|
||||
}
|
||||
|
||||
export interface CifsBackupTarget extends BaseBackupTarget {
|
||||
type: 'cifs'
|
||||
hostname: string
|
||||
username: string
|
||||
}
|
||||
|
||||
export interface CloudBackupTarget extends BaseBackupTarget {
|
||||
type: 'cloud'
|
||||
provider: 'dropbox' | 'google-drive'
|
||||
}
|
||||
|
||||
export interface BackupRun {
|
||||
id: string
|
||||
'started-at': string
|
||||
'completed-at': string
|
||||
'package-ids': string[]
|
||||
job: BackupJob
|
||||
report: BackupReport
|
||||
}
|
||||
|
||||
export interface BackupJob {
|
||||
id: string
|
||||
name: string
|
||||
target: BackupTarget
|
||||
cron: string // '* * * * * *' https://cloud.google.com/scheduler/docs/configuring/cron-job-schedules
|
||||
'package-ids': string[]
|
||||
}
|
||||
|
||||
export interface BackupInfo {
|
||||
version: string
|
||||
timestamp: string
|
||||
'package-backups': {
|
||||
[id: string]: PackageBackupInfo
|
||||
}
|
||||
}
|
||||
|
||||
export interface PackageBackupInfo {
|
||||
title: string
|
||||
version: string
|
||||
'os-version': string
|
||||
timestamp: string
|
||||
}
|
||||
|
||||
export interface ServerSpecs {
|
||||
[key: string]: string | number
|
||||
}
|
||||
|
||||
export interface SSHKey {
|
||||
'created-at': string
|
||||
alg: string
|
||||
hostname: string
|
||||
fingerprint: string
|
||||
}
|
||||
|
||||
export type ServerNotifications = ServerNotification<any>[]
|
||||
|
||||
export interface ServerNotification<T extends number> {
|
||||
id: number
|
||||
'package-id': string | null
|
||||
'created-at': string
|
||||
code: T
|
||||
level: NotificationLevel
|
||||
title: string
|
||||
message: string
|
||||
data: NotificationData<T>
|
||||
}
|
||||
|
||||
export enum NotificationLevel {
|
||||
Success = 'success',
|
||||
Info = 'info',
|
||||
Warning = 'warning',
|
||||
Error = 'error',
|
||||
}
|
||||
|
||||
export type NotificationData<T> = T extends 0
|
||||
? null
|
||||
: T extends 1
|
||||
? BackupReport
|
||||
: any
|
||||
|
||||
export interface BackupReport {
|
||||
server: {
|
||||
attempted: boolean
|
||||
error: string | null
|
||||
}
|
||||
packages: {
|
||||
[id: string]: {
|
||||
error: string | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface AvailableWifi {
|
||||
ssid: string
|
||||
strength: number
|
||||
security: string[]
|
||||
}
|
||||
|
||||
declare global {
|
||||
type Stringified<T> = string & {
|
||||
[P in keyof T]: T[P]
|
||||
}
|
||||
|
||||
interface JSON {
|
||||
stringify<T>(
|
||||
value: T,
|
||||
replacer?: (key: string, value: any) => any,
|
||||
space?: string | number,
|
||||
): string & Stringified<T>
|
||||
parse<T>(text: Stringified<T>, reviver?: (key: any, value: any) => any): T
|
||||
}
|
||||
}
|
||||
|
||||
export type Encrypted = {
|
||||
encrypted: string
|
||||
}
|
||||
|
||||
export type CloudProvider = 'dropbox' | 'google-drive'
|
||||
|
||||
export type DependencyError =
|
||||
| DependencyErrorNotInstalled
|
||||
| DependencyErrorNotRunning
|
||||
| DependencyErrorIncorrectVersion
|
||||
| DependencyErrorConfigUnsatisfied
|
||||
| DependencyErrorHealthChecksFailed
|
||||
| DependencyErrorTransitive
|
||||
|
||||
export enum DependencyErrorType {
|
||||
NotInstalled = 'not-installed',
|
||||
NotRunning = 'not-running',
|
||||
IncorrectVersion = 'incorrect-version',
|
||||
ConfigUnsatisfied = 'config-unsatisfied',
|
||||
HealthChecksFailed = 'health-checks-failed',
|
||||
InterfaceHealthChecksFailed = 'interface-health-checks-failed',
|
||||
Transitive = 'transitive',
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotInstalled {
|
||||
type: DependencyErrorType.NotInstalled
|
||||
}
|
||||
|
||||
export interface DependencyErrorNotRunning {
|
||||
type: DependencyErrorType.NotRunning
|
||||
}
|
||||
|
||||
export interface DependencyErrorIncorrectVersion {
|
||||
type: DependencyErrorType.IncorrectVersion
|
||||
expected: string // version range
|
||||
received: string // version
|
||||
}
|
||||
|
||||
export interface DependencyErrorConfigUnsatisfied {
|
||||
type: DependencyErrorType.ConfigUnsatisfied
|
||||
error: string
|
||||
}
|
||||
|
||||
export interface DependencyErrorHealthChecksFailed {
|
||||
type: DependencyErrorType.HealthChecksFailed
|
||||
check: HealthCheckResult
|
||||
}
|
||||
|
||||
export interface DependencyErrorTransitive {
|
||||
type: DependencyErrorType.Transitive
|
||||
}
|
||||
276
web/projects/ui/src/app/services/api/embassy-api.service.ts
Normal file
276
web/projects/ui/src/app/services/api/embassy-api.service.ts
Normal file
@@ -0,0 +1,276 @@
|
||||
import { Observable } from 'rxjs'
|
||||
import { Update } from 'patch-db-client'
|
||||
import { RR, BackupTargetType, Metrics } from './api.types'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { Log, SetupStatus } from '@start9labs/shared'
|
||||
import { WebSocketSubjectConfig } from 'rxjs/webSocket'
|
||||
|
||||
export abstract class ApiService {
|
||||
// http
|
||||
|
||||
// for getting static files: ex icons, instructions, licenses
|
||||
abstract getStatic(url: string): Promise<string>
|
||||
|
||||
// for sideloading packages
|
||||
abstract uploadPackage(guid: string, body: Blob): Promise<void>
|
||||
|
||||
abstract uploadFile(body: Blob): Promise<string>
|
||||
|
||||
// db
|
||||
|
||||
abstract setDbValue<T>(
|
||||
pathArr: Array<string | number>,
|
||||
value: T,
|
||||
): Promise<RR.SetDBValueRes>
|
||||
|
||||
// auth
|
||||
|
||||
abstract login(params: RR.LoginReq): Promise<RR.loginRes>
|
||||
|
||||
abstract logout(params: RR.LogoutReq): Promise<RR.LogoutRes>
|
||||
|
||||
abstract getSessions(params: RR.GetSessionsReq): Promise<RR.GetSessionsRes>
|
||||
|
||||
abstract killSessions(params: RR.KillSessionsReq): Promise<RR.KillSessionsRes>
|
||||
|
||||
abstract resetPassword(
|
||||
params: RR.ResetPasswordReq,
|
||||
): Promise<RR.ResetPasswordRes>
|
||||
|
||||
// server
|
||||
|
||||
abstract echo(params: RR.EchoReq, urlOverride?: string): Promise<RR.EchoRes>
|
||||
|
||||
abstract openPatchWebsocket$(): Observable<Update<DataModel>>
|
||||
|
||||
abstract openLogsWebsocket$(
|
||||
config: WebSocketSubjectConfig<Log>,
|
||||
): Observable<Log>
|
||||
|
||||
abstract openMetricsWebsocket$(
|
||||
config: WebSocketSubjectConfig<Metrics>,
|
||||
): Observable<Metrics>
|
||||
|
||||
abstract getSystemTime(
|
||||
params: RR.GetSystemTimeReq,
|
||||
): Promise<RR.GetSystemTimeRes>
|
||||
|
||||
abstract getServerLogs(
|
||||
params: RR.GetServerLogsReq,
|
||||
): Promise<RR.GetServerLogsRes>
|
||||
|
||||
abstract getKernelLogs(
|
||||
params: RR.GetServerLogsReq,
|
||||
): Promise<RR.GetServerLogsRes>
|
||||
|
||||
abstract getTorLogs(params: RR.GetServerLogsReq): Promise<RR.GetServerLogsRes>
|
||||
|
||||
abstract followServerLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes>
|
||||
|
||||
abstract followKernelLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes>
|
||||
|
||||
abstract followTorLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes>
|
||||
|
||||
abstract getServerMetrics(
|
||||
params: RR.GetServerMetricsReq,
|
||||
): Promise<RR.GetServerMetricsRes>
|
||||
|
||||
abstract updateServer(url?: string): Promise<RR.UpdateServerRes>
|
||||
|
||||
abstract restartServer(
|
||||
params: RR.RestartServerReq,
|
||||
): Promise<RR.RestartServerRes>
|
||||
|
||||
abstract shutdownServer(
|
||||
params: RR.ShutdownServerReq,
|
||||
): Promise<RR.ShutdownServerRes>
|
||||
|
||||
abstract systemRebuild(
|
||||
params: RR.SystemRebuildReq,
|
||||
): Promise<RR.SystemRebuildRes>
|
||||
|
||||
abstract repairDisk(params: RR.SystemRebuildReq): Promise<RR.SystemRebuildRes>
|
||||
|
||||
abstract resetTor(params: RR.ResetTorReq): Promise<RR.ResetTorRes>
|
||||
|
||||
abstract toggleZram(params: RR.ToggleZramReq): Promise<RR.ToggleZramRes>
|
||||
|
||||
// marketplace URLs
|
||||
|
||||
abstract marketplaceProxy<T>(
|
||||
path: string,
|
||||
params: Record<string, unknown>,
|
||||
url: string,
|
||||
): Promise<T>
|
||||
|
||||
abstract getEos(): Promise<RR.GetMarketplaceEosRes>
|
||||
|
||||
// notification
|
||||
|
||||
abstract getNotifications(
|
||||
params: RR.GetNotificationsReq,
|
||||
): Promise<RR.GetNotificationsRes>
|
||||
|
||||
abstract deleteNotification(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes>
|
||||
|
||||
abstract deleteAllNotifications(
|
||||
params: RR.DeleteAllNotificationsReq,
|
||||
): Promise<RR.DeleteAllNotificationsRes>
|
||||
|
||||
// wifi
|
||||
|
||||
abstract enableWifi(params: RR.EnableWifiReq): Promise<RR.EnableWifiRes>
|
||||
|
||||
abstract getWifi(
|
||||
params: RR.GetWifiReq,
|
||||
timeout: number,
|
||||
): Promise<RR.GetWifiRes>
|
||||
|
||||
abstract addWifi(params: RR.AddWifiReq): Promise<RR.AddWifiRes>
|
||||
|
||||
abstract connectWifi(params: RR.ConnectWifiReq): Promise<RR.ConnectWifiRes>
|
||||
|
||||
abstract deleteWifi(params: RR.DeleteWifiReq): Promise<RR.ConnectWifiRes>
|
||||
|
||||
// email
|
||||
|
||||
abstract testEmail(params: RR.TestEmailReq): Promise<RR.TestEmailRes>
|
||||
|
||||
abstract configureEmail(
|
||||
params: RR.ConfigureEmailReq,
|
||||
): Promise<RR.ConfigureEmailRes>
|
||||
|
||||
// ssh
|
||||
|
||||
abstract getSshKeys(params: RR.GetSSHKeysReq): Promise<RR.GetSSHKeysRes>
|
||||
|
||||
abstract addSshKey(params: RR.AddSSHKeyReq): Promise<RR.AddSSHKeyRes>
|
||||
|
||||
abstract deleteSshKey(params: RR.DeleteSSHKeyReq): Promise<RR.DeleteSSHKeyRes>
|
||||
|
||||
// backup
|
||||
|
||||
abstract getBackupTargets(
|
||||
params: RR.GetBackupTargetsReq,
|
||||
): Promise<RR.GetBackupTargetsRes>
|
||||
|
||||
abstract addBackupTarget(
|
||||
type: BackupTargetType,
|
||||
params:
|
||||
| RR.AddCifsBackupTargetReq
|
||||
| RR.AddCloudBackupTargetReq
|
||||
| RR.AddDiskBackupTargetReq,
|
||||
): Promise<RR.AddBackupTargetRes>
|
||||
|
||||
abstract updateBackupTarget(
|
||||
type: BackupTargetType,
|
||||
params:
|
||||
| RR.UpdateCifsBackupTargetReq
|
||||
| RR.UpdateCloudBackupTargetReq
|
||||
| RR.UpdateDiskBackupTargetReq,
|
||||
): Promise<RR.UpdateBackupTargetRes>
|
||||
|
||||
abstract removeBackupTarget(
|
||||
params: RR.RemoveBackupTargetReq,
|
||||
): Promise<RR.RemoveBackupTargetRes>
|
||||
|
||||
abstract getBackupJobs(
|
||||
params: RR.GetBackupJobsReq,
|
||||
): Promise<RR.GetBackupJobsRes>
|
||||
|
||||
abstract createBackupJob(
|
||||
params: RR.CreateBackupJobReq,
|
||||
): Promise<RR.CreateBackupJobRes>
|
||||
|
||||
abstract updateBackupJob(
|
||||
params: RR.UpdateBackupJobReq,
|
||||
): Promise<RR.UpdateBackupJobRes>
|
||||
|
||||
abstract deleteBackupJob(
|
||||
params: RR.DeleteBackupJobReq,
|
||||
): Promise<RR.DeleteBackupJobRes>
|
||||
|
||||
abstract getBackupRuns(
|
||||
params: RR.GetBackupRunsReq,
|
||||
): Promise<RR.GetBackupRunsRes>
|
||||
|
||||
abstract deleteBackupRuns(
|
||||
params: RR.DeleteBackupRunsReq,
|
||||
): Promise<RR.DeleteBackupRunsRes>
|
||||
|
||||
abstract getBackupInfo(
|
||||
params: RR.GetBackupInfoReq,
|
||||
): Promise<RR.GetBackupInfoRes>
|
||||
|
||||
abstract createBackup(params: RR.CreateBackupReq): Promise<RR.CreateBackupRes>
|
||||
|
||||
// package
|
||||
|
||||
abstract getPackageCredentials(
|
||||
params: RR.GetPackageCredentialsReq,
|
||||
): Promise<RR.GetPackageCredentialsRes>
|
||||
|
||||
abstract getPackageLogs(
|
||||
params: RR.GetPackageLogsReq,
|
||||
): Promise<RR.GetPackageLogsRes>
|
||||
|
||||
abstract followPackageLogs(
|
||||
params: RR.FollowPackageLogsReq,
|
||||
): Promise<RR.FollowPackageLogsRes>
|
||||
|
||||
abstract installPackage(
|
||||
params: RR.InstallPackageReq,
|
||||
): Promise<RR.InstallPackageRes>
|
||||
|
||||
abstract getPackageConfig(
|
||||
params: RR.GetPackageConfigReq,
|
||||
): Promise<RR.GetPackageConfigRes>
|
||||
|
||||
abstract drySetPackageConfig(
|
||||
params: RR.DrySetPackageConfigReq,
|
||||
): Promise<RR.DrySetPackageConfigRes>
|
||||
|
||||
abstract setPackageConfig(
|
||||
params: RR.SetPackageConfigReq,
|
||||
): Promise<RR.SetPackageConfigRes>
|
||||
|
||||
abstract restorePackages(
|
||||
params: RR.RestorePackagesReq,
|
||||
): Promise<RR.RestorePackagesRes>
|
||||
|
||||
abstract executePackageAction(
|
||||
params: RR.ExecutePackageActionReq,
|
||||
): Promise<RR.ExecutePackageActionRes>
|
||||
|
||||
abstract startPackage(params: RR.StartPackageReq): Promise<RR.StartPackageRes>
|
||||
|
||||
abstract restartPackage(
|
||||
params: RR.RestartPackageReq,
|
||||
): Promise<RR.RestartPackageRes>
|
||||
|
||||
abstract stopPackage(params: RR.StopPackageReq): Promise<RR.StopPackageRes>
|
||||
|
||||
abstract uninstallPackage(
|
||||
params: RR.UninstallPackageReq,
|
||||
): Promise<RR.UninstallPackageRes>
|
||||
|
||||
abstract dryConfigureDependency(
|
||||
params: RR.DryConfigureDependencyReq,
|
||||
): Promise<RR.DryConfigureDependencyRes>
|
||||
|
||||
abstract sideloadPackage(
|
||||
params: RR.SideloadPackageReq,
|
||||
): Promise<RR.SideloadPacakgeRes>
|
||||
|
||||
abstract getSetupStatus(): Promise<SetupStatus | null>
|
||||
|
||||
abstract followLogs(): Promise<string>
|
||||
}
|
||||
532
web/projects/ui/src/app/services/api/embassy-live-api.service.ts
Normal file
532
web/projects/ui/src/app/services/api/embassy-live-api.service.ts
Normal file
@@ -0,0 +1,532 @@
|
||||
import { Inject, Injectable } from '@angular/core'
|
||||
import {
|
||||
HttpOptions,
|
||||
HttpService,
|
||||
isRpcError,
|
||||
Log,
|
||||
Method,
|
||||
RpcError,
|
||||
RPCOptions,
|
||||
SetupStatus,
|
||||
} from '@start9labs/shared'
|
||||
import { ApiService } from './embassy-api.service'
|
||||
import { BackupTargetType, Metrics, RR } from './api.types'
|
||||
import { ConfigService } from '../config.service'
|
||||
import { webSocket, WebSocketSubjectConfig } from 'rxjs/webSocket'
|
||||
import { Observable, filter, firstValueFrom } from 'rxjs'
|
||||
import { AuthService } from '../auth.service'
|
||||
import { DOCUMENT } from '@angular/common'
|
||||
import { DataModel } from '../patch-db/data-model'
|
||||
import { PatchDB, pathFromArray, Update } from 'patch-db-client'
|
||||
import { getServerInfo } from 'src/app/util/get-server-info'
|
||||
|
||||
@Injectable()
|
||||
export class LiveApiService extends ApiService {
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private readonly document: Document,
|
||||
private readonly http: HttpService,
|
||||
private readonly config: ConfigService,
|
||||
private readonly auth: AuthService,
|
||||
private readonly patch: PatchDB<DataModel>,
|
||||
) {
|
||||
super()
|
||||
|
||||
// @ts-ignore
|
||||
this.document.defaultView.rpcClient = this
|
||||
}
|
||||
|
||||
// for getting static files: ex icons, instructions, licenses
|
||||
async getStatic(url: string): Promise<string> {
|
||||
return this.httpRequest({
|
||||
method: Method.GET,
|
||||
url,
|
||||
responseType: 'text',
|
||||
})
|
||||
}
|
||||
|
||||
// for sideloading packages
|
||||
async uploadPackage(guid: string, body: Blob): Promise<void> {
|
||||
return this.httpRequest({
|
||||
method: Method.POST,
|
||||
body,
|
||||
url: `/rest/rpc/${guid}`,
|
||||
responseType: 'text',
|
||||
})
|
||||
}
|
||||
|
||||
async uploadFile(body: Blob): Promise<string> {
|
||||
return this.httpRequest({
|
||||
method: Method.POST,
|
||||
body,
|
||||
url: `/rest/upload`,
|
||||
responseType: 'text',
|
||||
})
|
||||
}
|
||||
|
||||
// db
|
||||
|
||||
async setDbValue<T>(
|
||||
pathArr: Array<string | number>,
|
||||
value: T,
|
||||
): Promise<RR.SetDBValueRes> {
|
||||
const pointer = pathFromArray(pathArr)
|
||||
const params: RR.SetDBValueReq<T> = { pointer, value }
|
||||
return this.rpcRequest({ method: 'db.put.ui', params })
|
||||
}
|
||||
|
||||
// auth
|
||||
|
||||
async login(params: RR.LoginReq): Promise<RR.loginRes> {
|
||||
return this.rpcRequest({ method: 'auth.login', params })
|
||||
}
|
||||
|
||||
async logout(params: RR.LogoutReq): Promise<RR.LogoutRes> {
|
||||
return this.rpcRequest({ method: 'auth.logout', params })
|
||||
}
|
||||
|
||||
async getSessions(params: RR.GetSessionsReq): Promise<RR.GetSessionsRes> {
|
||||
return this.rpcRequest({ method: 'auth.session.list', params })
|
||||
}
|
||||
|
||||
async killSessions(params: RR.KillSessionsReq): Promise<RR.KillSessionsRes> {
|
||||
return this.rpcRequest({ method: 'auth.session.kill', params })
|
||||
}
|
||||
|
||||
async resetPassword(
|
||||
params: RR.ResetPasswordReq,
|
||||
): Promise<RR.ResetPasswordRes> {
|
||||
return this.rpcRequest({ method: 'auth.reset-password', params })
|
||||
}
|
||||
|
||||
// server
|
||||
|
||||
async echo(params: RR.EchoReq, urlOverride?: string): Promise<RR.EchoRes> {
|
||||
return this.rpcRequest({ method: 'echo', params }, urlOverride)
|
||||
}
|
||||
|
||||
openPatchWebsocket$(): Observable<Update<DataModel>> {
|
||||
const config: WebSocketSubjectConfig<Update<DataModel>> = {
|
||||
url: `/db`,
|
||||
closeObserver: {
|
||||
next: val => {
|
||||
if (val.reason === 'UNAUTHORIZED') this.auth.setUnverified()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return this.openWebsocket(config)
|
||||
}
|
||||
|
||||
async followLogs(): Promise<string> {
|
||||
return this.rpcRequest({ method: 'setup.logs.follow', params: {} })
|
||||
}
|
||||
|
||||
openLogsWebsocket$(config: WebSocketSubjectConfig<Log>): Observable<Log> {
|
||||
return this.openWebsocket(config)
|
||||
}
|
||||
|
||||
openMetricsWebsocket$(
|
||||
config: WebSocketSubjectConfig<Metrics>,
|
||||
): Observable<Metrics> {
|
||||
return this.openWebsocket(config)
|
||||
}
|
||||
|
||||
async getSystemTime(
|
||||
params: RR.GetSystemTimeReq,
|
||||
): Promise<RR.GetSystemTimeRes> {
|
||||
return this.rpcRequest({ method: 'server.time', params })
|
||||
}
|
||||
|
||||
async getServerLogs(
|
||||
params: RR.GetServerLogsReq,
|
||||
): Promise<RR.GetServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'server.logs', params })
|
||||
}
|
||||
|
||||
async getKernelLogs(
|
||||
params: RR.GetServerLogsReq,
|
||||
): Promise<RR.GetServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'server.kernel-logs', params })
|
||||
}
|
||||
|
||||
async getTorLogs(params: RR.GetServerLogsReq): Promise<RR.GetServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'net.tor.logs', params })
|
||||
}
|
||||
|
||||
async followServerLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'server.logs.follow', params })
|
||||
}
|
||||
|
||||
async followKernelLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'server.kernel-logs.follow', params })
|
||||
}
|
||||
|
||||
async followTorLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'net.tor.logs.follow', params })
|
||||
}
|
||||
|
||||
async getServerMetrics(
|
||||
params: RR.GetServerMetricsReq,
|
||||
): Promise<RR.GetServerMetricsRes> {
|
||||
return this.rpcRequest({ method: 'server.metrics', params })
|
||||
}
|
||||
|
||||
async updateServer(url?: string): Promise<RR.UpdateServerRes> {
|
||||
const params = {
|
||||
'marketplace-url': url || this.config.marketplace.start9,
|
||||
}
|
||||
return this.rpcRequest({ method: 'server.update', params })
|
||||
}
|
||||
|
||||
async restartServer(
|
||||
params: RR.RestartServerReq,
|
||||
): Promise<RR.RestartServerRes> {
|
||||
return this.rpcRequest({ method: 'server.restart', params })
|
||||
}
|
||||
|
||||
async shutdownServer(
|
||||
params: RR.ShutdownServerReq,
|
||||
): Promise<RR.ShutdownServerRes> {
|
||||
return this.rpcRequest({ method: 'server.shutdown', params })
|
||||
}
|
||||
|
||||
async systemRebuild(
|
||||
params: RR.RestartServerReq,
|
||||
): Promise<RR.RestartServerRes> {
|
||||
return this.rpcRequest({ method: 'server.rebuild', params })
|
||||
}
|
||||
|
||||
async repairDisk(params: RR.RestartServerReq): Promise<RR.RestartServerRes> {
|
||||
return this.rpcRequest({ method: 'disk.repair', params })
|
||||
}
|
||||
|
||||
async resetTor(params: RR.ResetTorReq): Promise<RR.ResetTorRes> {
|
||||
return this.rpcRequest({ method: 'net.tor.reset', params })
|
||||
}
|
||||
|
||||
async toggleZram(params: RR.ToggleZramReq): Promise<RR.ToggleZramRes> {
|
||||
return this.rpcRequest({ method: 'server.experimental.zram', params })
|
||||
}
|
||||
|
||||
// marketplace URLs
|
||||
|
||||
async marketplaceProxy<T>(
|
||||
path: string,
|
||||
qp: Record<string, string>,
|
||||
baseUrl: string,
|
||||
): Promise<T> {
|
||||
const fullUrl = `${baseUrl}${path}?${new URLSearchParams(qp).toString()}`
|
||||
return this.rpcRequest({
|
||||
method: 'marketplace.get',
|
||||
params: { url: fullUrl },
|
||||
})
|
||||
}
|
||||
|
||||
async getEos(): Promise<RR.GetMarketplaceEosRes> {
|
||||
const { id } = await getServerInfo(this.patch)
|
||||
const qp: RR.GetMarketplaceEosReq = { 'server-id': id }
|
||||
|
||||
return this.marketplaceProxy(
|
||||
'/eos/v0/latest',
|
||||
qp,
|
||||
this.config.marketplace.start9,
|
||||
)
|
||||
}
|
||||
|
||||
// notification
|
||||
|
||||
async getNotifications(
|
||||
params: RR.GetNotificationsReq,
|
||||
): Promise<RR.GetNotificationsRes> {
|
||||
return this.rpcRequest({ method: 'notification.list', params })
|
||||
}
|
||||
|
||||
async deleteNotification(
|
||||
params: RR.DeleteNotificationReq,
|
||||
): Promise<RR.DeleteNotificationRes> {
|
||||
return this.rpcRequest({ method: 'notification.delete', params })
|
||||
}
|
||||
|
||||
async deleteAllNotifications(
|
||||
params: RR.DeleteAllNotificationsReq,
|
||||
): Promise<RR.DeleteAllNotificationsRes> {
|
||||
return this.rpcRequest({
|
||||
method: 'notification.delete-before',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
// wifi
|
||||
|
||||
async enableWifi(params: RR.EnableWifiReq): Promise<RR.EnableWifiRes> {
|
||||
return this.rpcRequest({ method: 'wifi.enable', params })
|
||||
}
|
||||
|
||||
async getWifi(
|
||||
params: RR.GetWifiReq,
|
||||
timeout?: number,
|
||||
): Promise<RR.GetWifiRes> {
|
||||
return this.rpcRequest({ method: 'wifi.get', params, timeout })
|
||||
}
|
||||
|
||||
async addWifi(params: RR.AddWifiReq): Promise<RR.AddWifiRes> {
|
||||
return this.rpcRequest({ method: 'wifi.add', params })
|
||||
}
|
||||
|
||||
async connectWifi(params: RR.ConnectWifiReq): Promise<RR.ConnectWifiRes> {
|
||||
return this.rpcRequest({ method: 'wifi.connect', params })
|
||||
}
|
||||
|
||||
async deleteWifi(params: RR.DeleteWifiReq): Promise<RR.DeleteWifiRes> {
|
||||
return this.rpcRequest({ method: 'wifi.delete', params })
|
||||
}
|
||||
|
||||
// email
|
||||
|
||||
async testEmail(params: RR.TestEmailReq): Promise<RR.TestEmailRes> {
|
||||
return this.rpcRequest({ method: 'email.test', params })
|
||||
}
|
||||
|
||||
async configureEmail(
|
||||
params: RR.ConfigureEmailReq,
|
||||
): Promise<RR.ConfigureEmailRes> {
|
||||
return this.rpcRequest({ method: 'email.configure', params })
|
||||
}
|
||||
|
||||
// ssh
|
||||
|
||||
async getSshKeys(params: RR.GetSSHKeysReq): Promise<RR.GetSSHKeysRes> {
|
||||
return this.rpcRequest({ method: 'ssh.list', params })
|
||||
}
|
||||
|
||||
async addSshKey(params: RR.AddSSHKeyReq): Promise<RR.AddSSHKeyRes> {
|
||||
return this.rpcRequest({ method: 'ssh.add', params })
|
||||
}
|
||||
|
||||
async deleteSshKey(params: RR.DeleteSSHKeyReq): Promise<RR.DeleteSSHKeyRes> {
|
||||
return this.rpcRequest({ method: 'ssh.delete', params })
|
||||
}
|
||||
|
||||
// backup
|
||||
|
||||
async getBackupTargets(
|
||||
params: RR.GetBackupTargetsReq,
|
||||
): Promise<RR.GetBackupTargetsRes> {
|
||||
return this.rpcRequest({ method: 'backup.target.list', params })
|
||||
}
|
||||
|
||||
async addBackupTarget(
|
||||
type: BackupTargetType,
|
||||
params: RR.AddCifsBackupTargetReq | RR.AddCloudBackupTargetReq,
|
||||
): Promise<RR.AddBackupTargetRes> {
|
||||
params.path = params.path.replace('/\\/g', '/')
|
||||
return this.rpcRequest({ method: `backup.target.${type}.add`, params })
|
||||
}
|
||||
|
||||
async updateBackupTarget(
|
||||
type: BackupTargetType,
|
||||
params: RR.UpdateCifsBackupTargetReq | RR.UpdateCloudBackupTargetReq,
|
||||
): Promise<RR.UpdateBackupTargetRes> {
|
||||
return this.rpcRequest({ method: `backup.target.${type}.update`, params })
|
||||
}
|
||||
|
||||
async removeBackupTarget(
|
||||
params: RR.RemoveBackupTargetReq,
|
||||
): Promise<RR.RemoveBackupTargetRes> {
|
||||
return this.rpcRequest({ method: 'backup.target.remove', params })
|
||||
}
|
||||
|
||||
async getBackupJobs(
|
||||
params: RR.GetBackupJobsReq,
|
||||
): Promise<RR.GetBackupJobsRes> {
|
||||
return this.rpcRequest({ method: 'backup.job.list', params })
|
||||
}
|
||||
|
||||
async createBackupJob(
|
||||
params: RR.CreateBackupJobReq,
|
||||
): Promise<RR.CreateBackupJobRes> {
|
||||
return this.rpcRequest({ method: 'backup.job.create', params })
|
||||
}
|
||||
|
||||
async updateBackupJob(
|
||||
params: RR.UpdateBackupJobReq,
|
||||
): Promise<RR.UpdateBackupJobRes> {
|
||||
return this.rpcRequest({ method: 'backup.job.update', params })
|
||||
}
|
||||
|
||||
async deleteBackupJob(
|
||||
params: RR.DeleteBackupJobReq,
|
||||
): Promise<RR.DeleteBackupJobRes> {
|
||||
return this.rpcRequest({ method: 'backup.job.delete', params })
|
||||
}
|
||||
|
||||
async getBackupRuns(
|
||||
params: RR.GetBackupRunsReq,
|
||||
): Promise<RR.GetBackupRunsRes> {
|
||||
return this.rpcRequest({ method: 'backup.runs.list', params })
|
||||
}
|
||||
|
||||
async deleteBackupRuns(
|
||||
params: RR.DeleteBackupRunsReq,
|
||||
): Promise<RR.DeleteBackupRunsRes> {
|
||||
return this.rpcRequest({ method: 'backup.runs.delete', params })
|
||||
}
|
||||
|
||||
async getBackupInfo(
|
||||
params: RR.GetBackupInfoReq,
|
||||
): Promise<RR.GetBackupInfoRes> {
|
||||
return this.rpcRequest({ method: 'backup.target.info', params })
|
||||
}
|
||||
|
||||
async createBackup(params: RR.CreateBackupReq): Promise<RR.CreateBackupRes> {
|
||||
return this.rpcRequest({ method: 'backup.create', params })
|
||||
}
|
||||
|
||||
// package
|
||||
|
||||
async getPackageCredentials(
|
||||
params: RR.GetPackageCredentialsReq,
|
||||
): Promise<RR.GetPackageCredentialsRes> {
|
||||
return this.rpcRequest({ method: 'package.credentials', params })
|
||||
}
|
||||
|
||||
async getPackageLogs(
|
||||
params: RR.GetPackageLogsReq,
|
||||
): Promise<RR.GetPackageLogsRes> {
|
||||
return this.rpcRequest({ method: 'package.logs', params })
|
||||
}
|
||||
|
||||
async followPackageLogs(
|
||||
params: RR.FollowServerLogsReq,
|
||||
): Promise<RR.FollowServerLogsRes> {
|
||||
return this.rpcRequest({ method: 'package.logs.follow', params })
|
||||
}
|
||||
|
||||
async installPackage(
|
||||
params: RR.InstallPackageReq,
|
||||
): Promise<RR.InstallPackageRes> {
|
||||
return this.rpcRequest({ method: 'package.install', params })
|
||||
}
|
||||
|
||||
async getPackageConfig(
|
||||
params: RR.GetPackageConfigReq,
|
||||
): Promise<RR.GetPackageConfigRes> {
|
||||
return this.rpcRequest({ method: 'package.config.get', params })
|
||||
}
|
||||
|
||||
async drySetPackageConfig(
|
||||
params: RR.DrySetPackageConfigReq,
|
||||
): Promise<RR.DrySetPackageConfigRes> {
|
||||
return this.rpcRequest({ method: 'package.config.set.dry', params })
|
||||
}
|
||||
|
||||
async setPackageConfig(
|
||||
params: RR.SetPackageConfigReq,
|
||||
): Promise<RR.SetPackageConfigRes> {
|
||||
return this.rpcRequest({ method: 'package.config.set', params })
|
||||
}
|
||||
|
||||
async restorePackages(
|
||||
params: RR.RestorePackagesReq,
|
||||
): Promise<RR.RestorePackagesRes> {
|
||||
return this.rpcRequest({ method: 'package.backup.restore', params })
|
||||
}
|
||||
|
||||
async executePackageAction(
|
||||
params: RR.ExecutePackageActionReq,
|
||||
): Promise<RR.ExecutePackageActionRes> {
|
||||
return this.rpcRequest({ method: 'package.action', params })
|
||||
}
|
||||
|
||||
async startPackage(params: RR.StartPackageReq): Promise<RR.StartPackageRes> {
|
||||
return this.rpcRequest({ method: 'package.start', params })
|
||||
}
|
||||
|
||||
async restartPackage(
|
||||
params: RR.RestartPackageReq,
|
||||
): Promise<RR.RestartPackageRes> {
|
||||
return this.rpcRequest({ method: 'package.restart', params })
|
||||
}
|
||||
|
||||
async stopPackage(params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
|
||||
return this.rpcRequest({ method: 'package.stop', params })
|
||||
}
|
||||
|
||||
async uninstallPackage(
|
||||
params: RR.UninstallPackageReq,
|
||||
): Promise<RR.UninstallPackageRes> {
|
||||
return this.rpcRequest({ method: 'package.uninstall', params })
|
||||
}
|
||||
|
||||
async dryConfigureDependency(
|
||||
params: RR.DryConfigureDependencyReq,
|
||||
): Promise<RR.DryConfigureDependencyRes> {
|
||||
return this.rpcRequest({
|
||||
method: 'package.dependency.configure.dry',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
async sideloadPackage(
|
||||
params: RR.SideloadPackageReq,
|
||||
): Promise<RR.SideloadPacakgeRes> {
|
||||
return this.rpcRequest({
|
||||
method: 'package.sideload',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
async getSetupStatus() {
|
||||
return this.rpcRequest<SetupStatus | null>({
|
||||
method: 'setup.status',
|
||||
params: {},
|
||||
})
|
||||
}
|
||||
|
||||
private openWebsocket<T>(config: WebSocketSubjectConfig<T>): Observable<T> {
|
||||
const { location } = this.document.defaultView!
|
||||
const protocol = location.protocol === 'http:' ? 'ws' : 'wss'
|
||||
const host = location.host
|
||||
|
||||
config.url = `${protocol}://${host}/ws${config.url}`
|
||||
|
||||
return webSocket(config)
|
||||
}
|
||||
|
||||
private async rpcRequest<T>(
|
||||
options: RPCOptions,
|
||||
urlOverride?: string,
|
||||
): Promise<T> {
|
||||
const res = await this.http.rpcRequest<T>(options, urlOverride)
|
||||
const body = res.body
|
||||
|
||||
if (isRpcError(body)) {
|
||||
if (body.error.code === 34) {
|
||||
console.error('Unauthenticated, logging out')
|
||||
this.auth.setUnverified()
|
||||
}
|
||||
throw new RpcError(body.error)
|
||||
}
|
||||
|
||||
const patchSequence = res.headers.get('x-patch-sequence')
|
||||
if (patchSequence)
|
||||
await firstValueFrom(
|
||||
this.patch.cache$.pipe(
|
||||
filter(({ sequence }) => sequence >= Number(patchSequence)),
|
||||
),
|
||||
)
|
||||
|
||||
return body.result
|
||||
}
|
||||
|
||||
private async httpRequest<T>(opts: HttpOptions): Promise<T> {
|
||||
const res = await this.http.httpRequest<T>(opts)
|
||||
return res.body
|
||||
}
|
||||
}
|
||||
1178
web/projects/ui/src/app/services/api/embassy-mock-api.service.ts
Normal file
1178
web/projects/ui/src/app/services/api/embassy-mock-api.service.ts
Normal file
File diff suppressed because it is too large
Load Diff
85
web/projects/ui/src/app/services/api/mock-patch.ts
Normal file
85
web/projects/ui/src/app/services/api/mock-patch.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { BUILT_IN_WIDGETS } from 'src/app/apps/ui/pages/widgets/built-in/widgets'
|
||||
import { Mock } from './api.fixures'
|
||||
|
||||
export const mockPatchData: DataModel = {
|
||||
ui: {
|
||||
name: `Matt's Server`,
|
||||
'ack-welcome': '1.0.0',
|
||||
theme: 'Dark',
|
||||
widgets: BUILT_IN_WIDGETS.filter(
|
||||
({ id }) =>
|
||||
id === 'favorites' ||
|
||||
id === 'health' ||
|
||||
id === 'network' ||
|
||||
id === 'metrics',
|
||||
),
|
||||
marketplace: {
|
||||
'selected-url': 'https://registry.start9.com/',
|
||||
'known-hosts': {
|
||||
'https://registry.start9.com/': {
|
||||
name: 'Start9 Registry',
|
||||
},
|
||||
'https://community-registry.start9.com/': {},
|
||||
'https://beta-registry.start9.com/': {
|
||||
name: 'Dark9',
|
||||
},
|
||||
},
|
||||
},
|
||||
gaming: {
|
||||
snake: {
|
||||
'high-score': 0,
|
||||
},
|
||||
},
|
||||
'ack-instructions': {},
|
||||
},
|
||||
'server-info': {
|
||||
id: 'abcdefgh',
|
||||
version: '0.3.5',
|
||||
country: 'us',
|
||||
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
||||
'lan-address': 'https://adjective-noun.local',
|
||||
'tor-address': 'https://myveryownspecialtoraddress.onion',
|
||||
'ip-info': {
|
||||
eth0: {
|
||||
ipv4: '10.0.0.1',
|
||||
ipv6: null,
|
||||
},
|
||||
wlan0: {
|
||||
ipv4: '10.0.90.12',
|
||||
ipv6: 'FE80:CD00:0000:0CDE:1257:0000:211E:729CD',
|
||||
},
|
||||
},
|
||||
'last-wifi-region': null,
|
||||
'wifi-enabled': false,
|
||||
'unread-notification-count': 4,
|
||||
'eos-version-compat': '>=0.3.0 <=0.3.0.1',
|
||||
'status-info': {
|
||||
'current-backup': null,
|
||||
updated: false,
|
||||
'update-progress': null,
|
||||
restarting: false,
|
||||
'shutting-down': false,
|
||||
},
|
||||
hostname: 'random-words',
|
||||
pubkey: 'npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m',
|
||||
'ca-fingerprint': 'SHA-256: 63 2B 11 99 44 40 17 DF 37 FC C3 DF 0F 3D 15',
|
||||
'ntp-synced': false,
|
||||
zram: false,
|
||||
smtp: {
|
||||
server: '',
|
||||
port: 587,
|
||||
from: '',
|
||||
login: '',
|
||||
password: '',
|
||||
tls: true,
|
||||
},
|
||||
'password-hash':
|
||||
'$argon2d$v=19$m=1024,t=1,p=1$YXNkZmFzZGZhc2RmYXNkZg$Ceev1I901G6UwU+hY0sHrFZ56D+o+LNJ',
|
||||
platform: 'x86_64-nonfree',
|
||||
},
|
||||
'package-data': {
|
||||
bitcoind: Mock.bitcoind,
|
||||
lnd: Mock.lnd,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user