mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
0.3.0 refactor
ui: adds overlay layer to patch-db-client ui: getting towards mocks ui: cleans up factory init ui: nice type hack ui: live api for patch ui: api service source + http starts up ui: api source + http ui: rework patchdb config, pass stashTimeout into patchDbModel wires in temp patching into api service ui: example of wiring patchdbmodel into page begin integration remove unnecessary method linting first data rendering rework app initialization http source working for ssh delete call temp patches working entire Embassy tab complete not in kansas anymore ripping, saving progress progress for API request response types and endoint defs Update data-model.ts shambles, but in a good way progress big progress progress installed list working big progress progress progress begin marketplace redesign Update api-types.ts Update api-types.ts marketplace improvements cosmetic dependencies and recommendations begin nym auth approach install wizard restore flow and donations
This commit is contained in:
committed by
Aiden McClelland
parent
46f32cb90b
commit
8d01ebe8b2
@@ -2,124 +2,108 @@ import { Injectable } from '@angular/core'
|
||||
import { ModalController } from '@ionic/angular'
|
||||
import { AppConfigValuePage } from '../modals/app-config-value/app-config-value.page'
|
||||
import { ApiService } from './api/api.service'
|
||||
import { PropertySubject } from '../util/property-subject.util'
|
||||
import { S9Server, ServerModel } from '../models/server-model'
|
||||
import { ValueSpec } from '../app-config/config-types'
|
||||
import { ConfigSpec } from '../pkg-config/config-types'
|
||||
import { ConfigCursor } from '../pkg-config/config-cursor'
|
||||
import { SSHService } from '../pages/server-routes/developer-routes/dev-ssh-keys/ssh.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ServerConfigService {
|
||||
server: PropertySubject<S9Server>
|
||||
|
||||
constructor (
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly apiService: ApiService,
|
||||
private readonly serverModel: ServerModel,
|
||||
) {
|
||||
this.server = this.serverModel.watch()
|
||||
}
|
||||
private readonly sshService: SSHService,
|
||||
) { }
|
||||
|
||||
async presentModalValueEdit (key: string, current?: string) {
|
||||
const cursor = new ConfigCursor(serverConfig, { [key]: current }).seekNext(key)
|
||||
|
||||
async presentModalValueEdit (key: string, add = false) {
|
||||
const modal = await this.modalCtrl.create({
|
||||
backdropDismiss: false,
|
||||
component: AppConfigValuePage,
|
||||
presentingElement: await this.modalCtrl.getTop(),
|
||||
componentProps: {
|
||||
...this.getConfigSpec(key),
|
||||
value: add ? '' : this.server[key].getValue(),
|
||||
cursor,
|
||||
saveFn: this.saveFns[key],
|
||||
},
|
||||
})
|
||||
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
private getConfigSpec (key: string): SpecAndSaveFn {
|
||||
const configSpec: { [key: string]: SpecAndSaveFn } = {
|
||||
name: {
|
||||
spec: {
|
||||
type: 'string',
|
||||
name: 'Device Name',
|
||||
description: 'A unique label for this device.',
|
||||
nullable: false,
|
||||
// @TODO determine regex
|
||||
// pattern: '',
|
||||
patternDescription: 'Must be less than 40 characters',
|
||||
masked: false,
|
||||
copyable: true,
|
||||
},
|
||||
saveFn: (val: string) => {
|
||||
return this.apiService.patchServerConfig('name', val).then(() => this.serverModel.update({ name: val }))
|
||||
},
|
||||
},
|
||||
autoCheckUpdates: {
|
||||
spec: {
|
||||
type: 'boolean',
|
||||
name: 'Auto Check for Updates',
|
||||
description: 'On launch, EmabssyOS will automatically check for updates of itself and your installed services. Updating still requires user approval and action. No updates will ever be performed automatically.',
|
||||
default: true,
|
||||
},
|
||||
saveFn: (val: boolean) => {
|
||||
return this.apiService.patchServerConfig('autoCheckUpdates', val).then(() => this.serverModel.update({ autoCheckUpdates: val }))
|
||||
},
|
||||
},
|
||||
// password: {
|
||||
// spec: {
|
||||
// type: 'string',
|
||||
// name: 'Change Password',
|
||||
// description: 'The master password for your Embassy. Must contain at least 128 bits of entropy.',
|
||||
// nullable: false,
|
||||
// // @TODO figure out how to confirm min entropy
|
||||
// // pattern: '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[*.!@#$%^&*\]).{12,32}$',
|
||||
// patternDescription: 'Password too simple. Password must contain at least 128 bits of entroy.',
|
||||
// changeWarning: 'Changing your password will have no affect on old backups. In order to restore old backups, you must provide the password that was used to create them.',
|
||||
// masked: true,
|
||||
// copyable: true,
|
||||
// },
|
||||
// saveFn: (val: string) => {
|
||||
// return this.apiService.patchServerConfig('password', val)
|
||||
// },
|
||||
// },
|
||||
// alternativeRegistryUrl: {
|
||||
// spec: {
|
||||
// type: 'string',
|
||||
// name: 'Marketplace URL',
|
||||
// description: 'Used for connecting to an alternative service marketplace.',
|
||||
// nullable: true,
|
||||
// // @TODO regex for URL
|
||||
// // pattern: '',
|
||||
// patternDescription: 'Must be a valid URL',
|
||||
// changeWarning: 'Downloading services from an alternative marketplace could result in malicious or harmful code being installed on your device.',
|
||||
// masked: false,
|
||||
// copyable: true,
|
||||
// },
|
||||
// saveFn: (val: string) => {
|
||||
// return this.apiService.patchServerConfig('alternativeRegistryUrl', val).then(() => this.serverModel.update({ alternativeRegistryUrl: val }))
|
||||
// },
|
||||
// },
|
||||
ssh: {
|
||||
spec: {
|
||||
type: 'string',
|
||||
name: 'SSH Key',
|
||||
description: 'Add SSH keys to your Embassy to gain root access from the command line.',
|
||||
nullable: false,
|
||||
// @TODO regex for SSH Key
|
||||
// pattern: '',
|
||||
patternDescription: 'Must be a valid SSH key',
|
||||
masked: true,
|
||||
copyable: true,
|
||||
},
|
||||
saveFn: (val: string) => {
|
||||
return this.apiService.addSSHKey(val)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return configSpec[key]
|
||||
saveFns: { [key: string]: (val: any) => Promise<any> } = {
|
||||
name: async (value: string) => {
|
||||
return this.apiService.setDbValue({ pointer: 'ui/name', value })
|
||||
},
|
||||
autoCheckUpdates: async (value: boolean) => {
|
||||
return this.apiService.setDbValue({ pointer: 'ui/auto-check-updates', value })
|
||||
},
|
||||
ssh: async (pubkey: string) => {
|
||||
return this.sshService.add(pubkey)
|
||||
},
|
||||
registry: async (url: string) => {
|
||||
return this.apiService.setRegistry({ url })
|
||||
},
|
||||
// password: async (password: string) => {
|
||||
// return this.apiService.updatePassword({ password })
|
||||
// },
|
||||
}
|
||||
}
|
||||
|
||||
interface SpecAndSaveFn {
|
||||
spec: ValueSpec
|
||||
saveFn: (val: any) => Promise<any>
|
||||
const serverConfig: ConfigSpec = {
|
||||
name: {
|
||||
type: 'string',
|
||||
name: 'Device Name',
|
||||
description: 'A unique label for this device.',
|
||||
nullable: false,
|
||||
// @TODO determine regex
|
||||
// pattern: '',
|
||||
patternDescription: 'Must be less than 40 characters',
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
autoCheckUpdates: {
|
||||
type: 'boolean',
|
||||
name: 'Auto Check for Updates',
|
||||
description: 'On launch, EmabssyOS will automatically check for updates of itself and your installed services. Updating still requires user approval and action. No updates will ever be performed automatically.',
|
||||
default: true,
|
||||
},
|
||||
ssh: {
|
||||
type: 'string',
|
||||
name: 'SSH Key',
|
||||
description: 'Add SSH keys to your Embassy to gain root access from the command line.',
|
||||
nullable: false,
|
||||
// @TODO regex for SSH Key
|
||||
// pattern: '',
|
||||
patternDescription: 'Must be a valid SSH key',
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
registry: {
|
||||
type: 'string',
|
||||
name: 'Marketplace URL',
|
||||
description: 'The URL of the service marketplace. By default, your Embassy connects to the official Start9 Embassy Marketplace.',
|
||||
nullable: true,
|
||||
// @TODO regex for URL
|
||||
// pattern: '',
|
||||
patternDescription: 'Must be a valid URL',
|
||||
changeWarning: 'Downloading services from an alternative marketplace can result in malicious or harmful code being installed on your device.',
|
||||
default: 'https://registry.start9.com',
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
// password: {
|
||||
// type: 'string',
|
||||
// name: 'Change Password',
|
||||
// description: 'The master password for your Embassy. Must contain at least 128 bits of entropy.',
|
||||
// nullable: false,
|
||||
// // @TODO figure out how to confirm min entropy
|
||||
// // pattern: '^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[*.!@#$%^&*\]).{12,32}$',
|
||||
// patternDescription: 'Password too simple. Password must contain at least 128 bits of entroy.',
|
||||
// changeWarning: 'Changing your password will have no affect on old backups. In order to restore old backups, you must provide the password that was used to create them.',
|
||||
// masked: true,
|
||||
// copyable: true,
|
||||
// },
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user