mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
refine startup alerts, reversions in mocks
This commit is contained in:
committed by
Aiden McClelland
parent
8cfd98bbd0
commit
e8bf254b91
4
ui/package-lock.json
generated
4
ui/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-ui",
|
"name": "embassy-ui",
|
||||||
"version": "0.2.14",
|
"version": "0.3.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "embassy-ui",
|
"name": "embassy-ui",
|
||||||
"version": "0.2.14",
|
"version": "0.3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "^11.0.0",
|
"@angular/common": "^11.0.0",
|
||||||
"@angular/core": "^11.0.0",
|
"@angular/core": "^11.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-ui",
|
"name": "embassy-ui",
|
||||||
"version": "0.2.14",
|
"version": "0.3.0",
|
||||||
"description": "GUI for EmbassyOS",
|
"description": "GUI for EmbassyOS",
|
||||||
"author": "Start9 Labs",
|
"author": "Start9 Labs",
|
||||||
"homepage": "https://github.com/Start9Labs/embassy-ui",
|
"homepage": "https://github.com/Start9Labs/embassy-ui",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Storage } from '@ionic/storage'
|
|||||||
import { AuthService, AuthState } from './services/auth.service'
|
import { AuthService, AuthState } from './services/auth.service'
|
||||||
import { ApiService } from './services/api/embassy/embassy-api.service'
|
import { ApiService } from './services/api/embassy/embassy-api.service'
|
||||||
import { Router, RoutesRecognized } from '@angular/router'
|
import { Router, RoutesRecognized } from '@angular/router'
|
||||||
import { debounceTime, distinctUntilChanged, filter, finalize, takeWhile } from 'rxjs/operators'
|
import { debounceTime, distinctUntilChanged, filter, finalize, skip, take, takeWhile } from 'rxjs/operators'
|
||||||
import { AlertController, IonicSafeString, ToastController } from '@ionic/angular'
|
import { AlertController, IonicSafeString, ToastController } from '@ionic/angular'
|
||||||
import { LoaderService } from './services/loader.service'
|
import { LoaderService } from './services/loader.service'
|
||||||
import { Emver } from './services/emver.service'
|
import { Emver } from './services/emver.service'
|
||||||
@@ -14,6 +14,8 @@ import { HttpService } from './services/http.service'
|
|||||||
import { ServerStatus } from './services/patch-db/data-model'
|
import { ServerStatus } from './services/patch-db/data-model'
|
||||||
import { ConnectionFailure, ConnectionService } from './services/connection.service'
|
import { ConnectionFailure, ConnectionService } from './services/connection.service'
|
||||||
import { StartupAlertsService } from './services/startup-alerts.service'
|
import { StartupAlertsService } from './services/startup-alerts.service'
|
||||||
|
import { ConfigService } from './services/config.service'
|
||||||
|
import { isEmptyObject } from './util/misc.util'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@@ -63,6 +65,7 @@ export class AppComponent {
|
|||||||
private readonly startupAlertsService: StartupAlertsService,
|
private readonly startupAlertsService: StartupAlertsService,
|
||||||
private readonly toastCtrl: ToastController,
|
private readonly toastCtrl: ToastController,
|
||||||
private readonly patch: PatchDbService,
|
private readonly patch: PatchDbService,
|
||||||
|
private readonly config: ConfigService,
|
||||||
readonly splitPane: SplitPaneTracker,
|
readonly splitPane: SplitPaneTracker,
|
||||||
) {
|
) {
|
||||||
// set dark theme
|
// set dark theme
|
||||||
@@ -83,23 +86,33 @@ export class AppComponent {
|
|||||||
.subscribe(auth => {
|
.subscribe(auth => {
|
||||||
// VERIFIED
|
// VERIFIED
|
||||||
if (auth === AuthState.VERIFIED) {
|
if (auth === AuthState.VERIFIED) {
|
||||||
this.http.authReqEnabled = true
|
|
||||||
this.showMenu = true
|
|
||||||
this.patch.start()
|
this.patch.start()
|
||||||
this.connectionService.start()
|
|
||||||
// watch connection to display connectivity issues
|
this.patch.watch$()
|
||||||
this.watchConnection(auth)
|
.pipe(
|
||||||
// watch router to highlight selected menu item
|
filter(data => !isEmptyObject(data)),
|
||||||
this.watchRouter(auth)
|
take(1),
|
||||||
// watch status to display/hide maintenance page
|
)
|
||||||
this.watchStatus(auth)
|
.subscribe(_ => {
|
||||||
// watch unread notification count to display toast
|
this.showMenu = true
|
||||||
this.watchNotifications(auth)
|
this.router.navigate([''], { replaceUrl: true })
|
||||||
// run startup alerts
|
this.connectionService.start()
|
||||||
this.startupAlertsService.runChecks()
|
// watch connection to display connectivity issues
|
||||||
|
this.watchConnection(auth)
|
||||||
|
// watch router to highlight selected menu item
|
||||||
|
this.watchRouter(auth)
|
||||||
|
// watch status to display/hide maintenance page
|
||||||
|
this.watchStatus(auth)
|
||||||
|
// watch version to refresh browser window
|
||||||
|
this.watchVersion(auth)
|
||||||
|
// watch unread notification count to display toast
|
||||||
|
this.watchNotifications(auth)
|
||||||
|
// run startup alerts
|
||||||
|
this.startupAlertsService.runChecks()
|
||||||
|
})
|
||||||
|
|
||||||
// UNVERIFIED
|
// UNVERIFIED
|
||||||
} else if (auth === AuthState.UNVERIFIED) {
|
} else if (auth === AuthState.UNVERIFIED) {
|
||||||
this.http.authReqEnabled = false
|
|
||||||
this.showMenu = false
|
this.showMenu = false
|
||||||
this.connectionService.stop()
|
this.connectionService.stop()
|
||||||
this.patch.stop()
|
this.patch.stop()
|
||||||
@@ -178,16 +191,30 @@ export class AppComponent {
|
|||||||
)
|
)
|
||||||
.subscribe(status => {
|
.subscribe(status => {
|
||||||
const maintenance = '/maintenance'
|
const maintenance = '/maintenance'
|
||||||
const url = this.router.url
|
const route = this.router.url
|
||||||
if (status === ServerStatus.Running && url.startsWith(maintenance)) {
|
console.log('STATUS', status, 'URL', route)
|
||||||
|
if (status === ServerStatus.Running && route.startsWith(maintenance)) {
|
||||||
this.router.navigate([''], { replaceUrl: true })
|
this.router.navigate([''], { replaceUrl: true })
|
||||||
}
|
}
|
||||||
if ([ServerStatus.Updating, ServerStatus.BackingUp].includes(status) && !url.startsWith(maintenance)) {
|
if ([ServerStatus.Updating, ServerStatus.BackingUp].includes(status) && !route.startsWith(maintenance)) {
|
||||||
|
this.showMenu = false
|
||||||
this.router.navigate([maintenance], { replaceUrl: true })
|
this.router.navigate([maintenance], { replaceUrl: true })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private watchVersion (auth: AuthState): void {
|
||||||
|
this.patch.watch$('server-info', 'version')
|
||||||
|
.pipe(
|
||||||
|
takeWhile(() => auth === AuthState.VERIFIED),
|
||||||
|
)
|
||||||
|
.subscribe(version => {
|
||||||
|
if (this.emver.compare(this.config.version, version) !== 0) {
|
||||||
|
this.presentAlertRefreshNeeded()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private watchNotifications (auth: AuthState): void {
|
private watchNotifications (auth: AuthState): void {
|
||||||
let previous: number
|
let previous: number
|
||||||
this.patch.watch$('server-info', 'unread-notification-count')
|
this.patch.watch$('server-info', 'unread-notification-count')
|
||||||
@@ -202,7 +229,25 @@ export class AppComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async presentAlertRefreshNeeded () {
|
||||||
|
const alert = await this.alertCtrl.create({
|
||||||
|
backdropDismiss: false,
|
||||||
|
header: 'Refresh Needed',
|
||||||
|
message: 'Your EmbassyOS UI is out of date. Hard refresh the page to get the latest UI.',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: 'Refresh Page',
|
||||||
|
handler: () => {
|
||||||
|
location.reload()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
await alert.present()
|
||||||
|
}
|
||||||
|
|
||||||
async presentAlertLogout () {
|
async presentAlertLogout () {
|
||||||
|
// @TODO warn user no way to recover Embassy if logout and forget password. Maybe require password to logout?
|
||||||
const alert = await this.alertCtrl.create({
|
const alert = await this.alertCtrl.create({
|
||||||
backdropDismiss: false,
|
backdropDismiss: false,
|
||||||
header: 'Caution',
|
header: 'Caution',
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { CanActivate, Router, CanActivateChild } from '@angular/router'
|
import { CanActivate, Router, CanActivateChild } from '@angular/router'
|
||||||
import { tap } from 'rxjs/operators'
|
|
||||||
import { ServerStatus } from '../services/patch-db/data-model'
|
import { ServerStatus } from '../services/patch-db/data-model'
|
||||||
import { PatchDbService } from '../services/patch-db/patch-db.service'
|
import { PatchDbService } from '../services/patch-db/patch-db.service'
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export class UnmaintenanceGuard implements CanActivate {
|
|||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
private readonly patch: PatchDbService,
|
private readonly patch: PatchDbService,
|
||||||
) {
|
) {
|
||||||
this.patch.sequence$.subscribe(_ => {
|
this.patch.watch$('server-info', 'status').subscribe(status => {
|
||||||
this.serverStatus = this.patch.data['server-info'].status
|
this.serverStatus = status
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<ion-header>
|
<ion-header>
|
||||||
<ion-toolbar>
|
<ion-toolbar>
|
||||||
<ion-title >
|
<ion-title >
|
||||||
<ion-label style="font-size: 20px;" class="ion-text-wrap">Welcome to 0.2.14!</ion-label>
|
<ion-label style="font-size: 20px;" class="ion-text-wrap">Welcome to {{ version }}!</ion-label>
|
||||||
</ion-title>
|
</ion-title>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="close-button">
|
<div class="close-button">
|
||||||
<ion-button fill="outline" (click)="dismiss()">
|
<ion-button fill="outline" color="dark" (click)="dismiss()">
|
||||||
Begin
|
Begin
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
import { NavController } from '@ionic/angular'
|
import { LoadingController } from '@ionic/angular'
|
||||||
import { AuthService } from 'src/app/services/auth.service'
|
import { AuthService } from 'src/app/services/auth.service'
|
||||||
import { LoaderService } from 'src/app/services/loader.service'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'login',
|
selector: 'login',
|
||||||
@@ -12,15 +11,18 @@ export class LoginPage {
|
|||||||
password = ''
|
password = ''
|
||||||
unmasked = false
|
unmasked = false
|
||||||
error = ''
|
error = ''
|
||||||
|
loader: HTMLIonLoadingElement
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
private readonly loader: LoaderService,
|
private readonly loadingCtrl: LoadingController,
|
||||||
private readonly navCtrl: NavController,
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ionViewDidEnter () {
|
ngOnDestroy () {
|
||||||
this.error = ''
|
if (this.loader) {
|
||||||
|
this.loader.dismiss()
|
||||||
|
this.loader = undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMask () {
|
toggleMask () {
|
||||||
@@ -28,14 +30,21 @@ export class LoginPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async submit () {
|
async submit () {
|
||||||
|
this.error = ''
|
||||||
|
|
||||||
|
this.loader = await this.loadingCtrl.create({
|
||||||
|
message: 'Authenticating',
|
||||||
|
spinner: 'lines',
|
||||||
|
})
|
||||||
|
await this.loader.present()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.loader.displayDuringP(
|
await this.authService.login(this.password)
|
||||||
this.authService.login(this.password),
|
this.loader.message = 'Loading Embassy Data'
|
||||||
)
|
|
||||||
this.password = ''
|
this.password = ''
|
||||||
await this.navCtrl.navigateForward(['/'])
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.error = e.message
|
this.error = e.message
|
||||||
|
this.loader.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<ion-content *ngIf="patch.data['serverInfo'].status as status">
|
<ion-content *ngIf="patch.data['server-info'].status as status">
|
||||||
|
|
||||||
<ion-grid style="height: 100%;">
|
<ion-grid style="height: 100%;">
|
||||||
<ion-row class="ion-align-items-center ion-text-center" style="height: 100%;">
|
<ion-row class="ion-align-items-center ion-text-center" style="height: 100%;">
|
||||||
<ion-col>
|
<ion-col>
|
||||||
<ion-spinner name="lines" color="warning"></ion-spinner>
|
<ion-spinner name="lines" color="warning"></ion-spinner>
|
||||||
<p *ngIf="status === ServerStatus.Updating">Updating Embassy</p>
|
<p *ngIf="status === ServerStatus.Updating">Embassy is updating</p>
|
||||||
<p *ngIf="status === ServerStatus.BackingUp">Embassy is backing up</p>
|
<p *ngIf="status === ServerStatus.BackingUp">Embassy is backing up</p>
|
||||||
</ion-col>
|
</ion-col>
|
||||||
</ion-row>
|
</ion-row>
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { DependencyErrorType, DockerIoFormat, Manifest, PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model'
|
import { DockerIoFormat, Manifest, PackageDataEntry, PackageMainStatus, PackageState } from 'src/app/services/patch-db/data-model'
|
||||||
import { MarketplacePkg, Metric, NotificationLevel, RR, ServerNotification, ServerNotifications } from './api.types'
|
import { MarketplacePkg, Metric, NotificationLevel, RR, ServerNotifications } from './api.types'
|
||||||
|
|
||||||
export module Mock {
|
export module Mock {
|
||||||
|
|
||||||
export const MarketplaceEos: RR.GetMarketplaceEOSRes = {
|
export const MarketplaceEos: RR.GetMarketplaceEOSRes = {
|
||||||
version: '1.0.0',
|
version: '0.3.1',
|
||||||
headline: 'Our biggest release ever.',
|
headline: 'Our biggest release ever.',
|
||||||
'release-notes': { '1.0.0': 'Some **Markdown** release _notes_' },
|
'release-notes': {
|
||||||
|
'0.3.1': 'Some **Markdown** release _notes_ for 0.3.1',
|
||||||
|
'0.3.0': 'Some **Markdown** release _notes_ from a prior version',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReleaseNotes: RR.GetReleaseNotesRes = {
|
export const ReleaseNotes: RR.GetReleaseNotesRes = {
|
||||||
@@ -375,7 +378,7 @@ export module Mock {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AvailableShow: {
|
export const MarketplacePkgs: {
|
||||||
[id: string]: {
|
[id: string]: {
|
||||||
[version: string]: MarketplacePkg
|
[version: string]: MarketplacePkg
|
||||||
}
|
}
|
||||||
@@ -513,108 +516,7 @@ export module Mock {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AvailableList: RR.GetMarketplacePackagesRes = Object.values(Mock.AvailableShow).map(service => service['latest'])
|
export const MarketplacePkgsList: RR.GetMarketplacePackagesRes = Object.values(Mock.MarketplacePkgs).map(service => service['latest'])
|
||||||
|
|
||||||
export const bitcoind: PackageDataEntry = {
|
|
||||||
state: PackageState.Installed,
|
|
||||||
'static-files': {
|
|
||||||
license: 'licenseUrl', // /public/package-data/bitcoind/0.21.1/LICENSE.md,
|
|
||||||
icon: 'assets/img/service-icons/bitcoind.png',
|
|
||||||
instructions: 'instructionsUrl', // /public/package-data/bitcoind/0.21.1/INSTRUCTIONS.md
|
|
||||||
},
|
|
||||||
manifest: {
|
|
||||||
...MockManifestBitcoind,
|
|
||||||
version: '0.20.0',
|
|
||||||
},
|
|
||||||
installed: {
|
|
||||||
status: {
|
|
||||||
configured: true,
|
|
||||||
main: {
|
|
||||||
status: PackageMainStatus.Running,
|
|
||||||
started: new Date().toISOString(),
|
|
||||||
health: { },
|
|
||||||
},
|
|
||||||
'dependency-errors': { },
|
|
||||||
},
|
|
||||||
'interface-info': {
|
|
||||||
ip: '10.0.0.1',
|
|
||||||
addresses: {
|
|
||||||
ui: {
|
|
||||||
'tor-address': 'bitcoind-ui-address.onion',
|
|
||||||
'lan-address': 'bitcoind-ui-address.local',
|
|
||||||
},
|
|
||||||
rpc: {
|
|
||||||
'tor-address': 'bitcoind-rpc-address.onion',
|
|
||||||
'lan-address': 'bitcoind-rpc-address.local',
|
|
||||||
},
|
|
||||||
p2p: {
|
|
||||||
'tor-address': 'bitcoind-p2p-address.onion',
|
|
||||||
'lan-address': 'bitcoind-p2p-address.local',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'system-pointers': [],
|
|
||||||
'current-dependents': {
|
|
||||||
'lnd': {
|
|
||||||
pointers: [],
|
|
||||||
'health-checks': [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'current-dependencies': { },
|
|
||||||
},
|
|
||||||
'install-progress': undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const lnd: PackageDataEntry = {
|
|
||||||
state: PackageState.Installed,
|
|
||||||
'static-files': {
|
|
||||||
license: 'licenseUrl', // /public/package-data/lnd/0.21.1/LICENSE.md,
|
|
||||||
icon: 'assets/img/service-icons/lnd.png',
|
|
||||||
instructions: 'instructionsUrl', // /public/package-data/lnd/0.21.1/INSTRUCTIONS.md
|
|
||||||
},
|
|
||||||
manifest: MockManifestLnd,
|
|
||||||
installed: {
|
|
||||||
status: {
|
|
||||||
configured: true,
|
|
||||||
main: {
|
|
||||||
status: PackageMainStatus.Stopped,
|
|
||||||
},
|
|
||||||
'dependency-errors': {
|
|
||||||
'bitcoin-proxy': {
|
|
||||||
type: DependencyErrorType.NotInstalled,
|
|
||||||
title: Mock.MockManifestBitcoinProxy.title,
|
|
||||||
icon: 'assets/img/service-icons/bitcoin-proxy.png',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'interface-info': {
|
|
||||||
ip: '10.0.0.1',
|
|
||||||
addresses: {
|
|
||||||
rpc: {
|
|
||||||
'tor-address': 'lnd-rpc-address.onion',
|
|
||||||
'lan-address': 'lnd-rpc-address.local',
|
|
||||||
},
|
|
||||||
grpc: {
|
|
||||||
'tor-address': 'lnd-grpc-address.onion',
|
|
||||||
'lan-address': 'lnd-grpc-address.local',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'system-pointers': [],
|
|
||||||
'current-dependents': { },
|
|
||||||
'current-dependencies': {
|
|
||||||
'bitcoind': {
|
|
||||||
pointers: [],
|
|
||||||
'health-checks': [],
|
|
||||||
},
|
|
||||||
'bitcoin-proxy': {
|
|
||||||
pointers: [],
|
|
||||||
'health-checks': [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'install-progress': undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const bitcoinproxy: PackageDataEntry = {
|
export const bitcoinproxy: PackageDataEntry = {
|
||||||
state: PackageState.Installed,
|
state: PackageState.Installed,
|
||||||
@@ -660,68 +562,27 @@ export module Mock {
|
|||||||
'install-progress': undefined,
|
'install-progress': undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DbDump: RR.GetDumpRes = {
|
export const Notifications: ServerNotifications = [
|
||||||
id: 1,
|
{
|
||||||
expireId: null,
|
id: '123e4567-e89b-12d3-a456-426655440000',
|
||||||
value: {
|
'package-id': null,
|
||||||
'server-info': {
|
'created-at': '2019-12-26T14:20:30.872Z',
|
||||||
id: 'start9-abcdefgmm',
|
code: 1,
|
||||||
version: '1.0.0',
|
level: NotificationLevel.Success,
|
||||||
status: ServerStatus.Running,
|
title: 'Backup Complete',
|
||||||
'lan-address': 'start9-abcdefgh.local',
|
message: 'Embassy and services have been successfully backed up.',
|
||||||
'tor-address': 'myveryownspecialtoraddress.onion',
|
data: {
|
||||||
wifi: {
|
server: {
|
||||||
ssids: ['Goosers', 'Goosers5G'],
|
attempted: true,
|
||||||
selected: 'Goosers5G',
|
|
||||||
connected: 'Goosers5G',
|
|
||||||
},
|
|
||||||
'package-marketplace': 'https://registry.start9.com',
|
|
||||||
'eos-marketplace': 'https://registry.start9.com',
|
|
||||||
'unread-notification-count': 4,
|
|
||||||
specs: {
|
|
||||||
CPU: 'Cortex-A72: 4 Cores @1500MHz',
|
|
||||||
Disk: '1TB SSD',
|
|
||||||
Memory: '8GB',
|
|
||||||
},
|
|
||||||
'connection-addresses': {
|
|
||||||
tor: [],
|
|
||||||
clearnet: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'package-data': {
|
|
||||||
'bitcoind': bitcoind,
|
|
||||||
'lnd': lnd,
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
'welcome-ack': '1.0.0',
|
|
||||||
'auto-check-updates': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export const notification1: ServerNotification<1> = {
|
|
||||||
id: '123e4567-e89b-12d3-a456-426655440000',
|
|
||||||
'package-id': null,
|
|
||||||
'created-at': '2019-12-26T14:20:30.872Z',
|
|
||||||
code: 1,
|
|
||||||
level: NotificationLevel.Success,
|
|
||||||
title: 'Backup Complete',
|
|
||||||
message: 'Embassy and services have been successfully backed up.',
|
|
||||||
data: {
|
|
||||||
server: {
|
|
||||||
attempted: true,
|
|
||||||
error: null,
|
|
||||||
},
|
|
||||||
packages: {
|
|
||||||
'bitcoind': {
|
|
||||||
error: null,
|
error: null,
|
||||||
},
|
},
|
||||||
|
packages: {
|
||||||
|
'bitcoind': {
|
||||||
|
error: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
export const Notifications: ServerNotifications = [
|
|
||||||
notification1,
|
|
||||||
{
|
{
|
||||||
id: '123e4567-e89b-12d3-a456-426655440001',
|
id: '123e4567-e89b-12d3-a456-426655440001',
|
||||||
'package-id': 'bitcoind',
|
'package-id': 'bitcoind',
|
||||||
@@ -1435,4 +1296,144 @@ export module Mock {
|
|||||||
rpcallowip: [],
|
rpcallowip: [],
|
||||||
rpcauth: ['matt: 8273gr8qwoidm1uid91jeh8y23gdio1kskmwejkdnm'],
|
rpcauth: ['matt: 8273gr8qwoidm1uid91jeh8y23gdio1kskmwejkdnm'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// export const bitcoind: PackageDataEntry = {
|
||||||
|
// state: PackageState.Installed,
|
||||||
|
// 'static-files': {
|
||||||
|
// license: 'licenseUrl', // /public/package-data/bitcoind/0.21.1/LICENSE.md,
|
||||||
|
// icon: 'assets/img/service-icons/bitcoind.png',
|
||||||
|
// instructions: 'instructionsUrl', // /public/package-data/bitcoind/0.21.1/INSTRUCTIONS.md
|
||||||
|
// },
|
||||||
|
// manifest: {
|
||||||
|
// ...MockManifestBitcoind,
|
||||||
|
// version: '0.20.0',
|
||||||
|
// },
|
||||||
|
// installed: {
|
||||||
|
// status: {
|
||||||
|
// configured: true,
|
||||||
|
// main: {
|
||||||
|
// status: PackageMainStatus.Running,
|
||||||
|
// started: new Date().toISOString(),
|
||||||
|
// health: { },
|
||||||
|
// },
|
||||||
|
// 'dependency-errors': { },
|
||||||
|
// },
|
||||||
|
// 'interface-info': {
|
||||||
|
// ip: '10.0.0.1',
|
||||||
|
// addresses: {
|
||||||
|
// ui: {
|
||||||
|
// 'tor-address': 'bitcoind-ui-address.onion',
|
||||||
|
// 'lan-address': 'bitcoind-ui-address.local',
|
||||||
|
// },
|
||||||
|
// rpc: {
|
||||||
|
// 'tor-address': 'bitcoind-rpc-address.onion',
|
||||||
|
// 'lan-address': 'bitcoind-rpc-address.local',
|
||||||
|
// },
|
||||||
|
// p2p: {
|
||||||
|
// 'tor-address': 'bitcoind-p2p-address.onion',
|
||||||
|
// 'lan-address': 'bitcoind-p2p-address.local',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'system-pointers': [],
|
||||||
|
// 'current-dependents': {
|
||||||
|
// 'lnd': {
|
||||||
|
// pointers: [],
|
||||||
|
// 'health-checks': [],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'current-dependencies': { },
|
||||||
|
// },
|
||||||
|
// 'install-progress': undefined,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const lnd: PackageDataEntry = {
|
||||||
|
// state: PackageState.Installed,
|
||||||
|
// 'static-files': {
|
||||||
|
// license: 'licenseUrl', // /public/package-data/lnd/0.21.1/LICENSE.md,
|
||||||
|
// icon: 'assets/img/service-icons/lnd.png',
|
||||||
|
// instructions: 'instructionsUrl', // /public/package-data/lnd/0.21.1/INSTRUCTIONS.md
|
||||||
|
// },
|
||||||
|
// manifest: MockManifestLnd,
|
||||||
|
// installed: {
|
||||||
|
// status: {
|
||||||
|
// configured: true,
|
||||||
|
// main: {
|
||||||
|
// status: PackageMainStatus.Stopped,
|
||||||
|
// },
|
||||||
|
// 'dependency-errors': {
|
||||||
|
// 'bitcoin-proxy': {
|
||||||
|
// type: DependencyErrorType.NotInstalled,
|
||||||
|
// title: Mock.MockManifestBitcoinProxy.title,
|
||||||
|
// icon: 'assets/img/service-icons/bitcoin-proxy.png',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'interface-info': {
|
||||||
|
// ip: '10.0.0.1',
|
||||||
|
// addresses: {
|
||||||
|
// rpc: {
|
||||||
|
// 'tor-address': 'lnd-rpc-address.onion',
|
||||||
|
// 'lan-address': 'lnd-rpc-address.local',
|
||||||
|
// },
|
||||||
|
// grpc: {
|
||||||
|
// 'tor-address': 'lnd-grpc-address.onion',
|
||||||
|
// 'lan-address': 'lnd-grpc-address.local',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'system-pointers': [],
|
||||||
|
// 'current-dependents': { },
|
||||||
|
// 'current-dependencies': {
|
||||||
|
// 'bitcoind': {
|
||||||
|
// pointers: [],
|
||||||
|
// 'health-checks': [],
|
||||||
|
// },
|
||||||
|
// 'bitcoin-proxy': {
|
||||||
|
// pointers: [],
|
||||||
|
// 'health-checks': [],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'install-progress': undefined,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const DbDump: RR.GetDumpRes = {
|
||||||
|
// id: 1,
|
||||||
|
// expireId: null,
|
||||||
|
// value: {
|
||||||
|
// 'server-info': {
|
||||||
|
// id: 'start9-abcdefgmm',
|
||||||
|
// version: '1.0.0',
|
||||||
|
// status: ServerStatus.Running,
|
||||||
|
// 'lan-address': 'start9-abcdefgh.local',
|
||||||
|
// 'tor-address': 'myveryownspecialtoraddress.onion',
|
||||||
|
// wifi: {
|
||||||
|
// ssids: ['Goosers', 'Goosers5G'],
|
||||||
|
// selected: 'Goosers5G',
|
||||||
|
// connected: 'Goosers5G',
|
||||||
|
// },
|
||||||
|
// 'eos-marketplace': 'https://registry.start9.com',
|
||||||
|
// 'package-marketplace': 'https://registry.start9.com',
|
||||||
|
// 'unread-notification-count': 4,
|
||||||
|
// specs: {
|
||||||
|
// CPU: 'Cortex-A72: 4 Cores @1500MHz',
|
||||||
|
// Disk: '1TB SSD',
|
||||||
|
// Memory: '8GB',
|
||||||
|
// },
|
||||||
|
// 'connection-addresses': {
|
||||||
|
// tor: ['http://privacy34kn4ez3y3nijweec6w4g54i3g54sdv7r5mr6soma3w4begyd.onion'],
|
||||||
|
// clearnet: ['https://start9.com'],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// 'package-data': {
|
||||||
|
// 'bitcoind': bitcoind,
|
||||||
|
// 'lnd': lnd,
|
||||||
|
// },
|
||||||
|
// ui: {
|
||||||
|
// 'welcome-ack': '1.0.0',
|
||||||
|
// 'auto-check-updates': true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
|
|||||||
// )()
|
// )()
|
||||||
|
|
||||||
// password
|
// password
|
||||||
abstract updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes>
|
// abstract updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes>
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
|
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ export class LiveApiService extends ApiService {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// password
|
// password
|
||||||
async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
// async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
||||||
return this.http.rpcRequest({ method: 'password.set', params })
|
// return this.http.rpcRequest({ method: 'password.set', params })
|
||||||
}
|
// }
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { pauseFor } from '../../../util/misc.util'
|
import { pauseFor } from '../../../util/misc.util'
|
||||||
import { ApiService } from './embassy-api.service'
|
import { ApiService } from './embassy-api.service'
|
||||||
import { PatchOp } from 'patch-db-client'
|
import { Operation, PatchOp } from 'patch-db-client'
|
||||||
import { PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model'
|
import { PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model'
|
||||||
import { RR, WithRevision } from '../api.types'
|
import { RR, WithRevision } from '../api.types'
|
||||||
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
|
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
|
||||||
@@ -12,7 +12,7 @@ import { ConfigService } from '../../config.service'
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MockApiService extends ApiService {
|
export class MockApiService extends ApiService {
|
||||||
welcomeAck = false
|
private readonly revertTime = 4000
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private readonly http: HttpService,
|
private readonly http: HttpService,
|
||||||
@@ -32,7 +32,7 @@ export class MockApiService extends ApiService {
|
|||||||
// ...Mock.DbDump,
|
// ...Mock.DbDump,
|
||||||
// id: this.nextSequence(),
|
// id: this.nextSequence(),
|
||||||
// }
|
// }
|
||||||
return this.http.rpcRequest({ method: 'db.revisions', params: { since } })
|
return this.http.rpcRequest<RR.GetRevisionsRes>({ method: 'db.revisions', params: { since } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDump (): Promise<RR.GetDumpRes> {
|
async getDump (): Promise<RR.GetDumpRes> {
|
||||||
@@ -41,7 +41,7 @@ export class MockApiService extends ApiService {
|
|||||||
// ...Mock.DbDump,
|
// ...Mock.DbDump,
|
||||||
// id: this.nextSequence(),
|
// id: this.nextSequence(),
|
||||||
// }
|
// }
|
||||||
return this.http.rpcRequest({ method: 'db.dump' })
|
return this.http.rpcRequest<RR.GetDumpRes>({ method: 'db.dump' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async setDbValueRaw (params: RR.SetDBValueReq): Promise<RR.SetDBValueRes> {
|
async setDbValueRaw (params: RR.SetDBValueReq): Promise<RR.SetDBValueRes> {
|
||||||
@@ -60,7 +60,7 @@ export class MockApiService extends ApiService {
|
|||||||
// expireId: null,
|
// expireId: null,
|
||||||
// },
|
// },
|
||||||
// }
|
// }
|
||||||
return this.http.rpcRequest({ method: 'db.put.ui', params })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.put.ui', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
@@ -94,14 +94,41 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async updateServerRaw (params: RR.UpdateServerReq): Promise<RR.UpdateServerRes> {
|
async updateServerRaw (params: RR.UpdateServerReq): Promise<RR.UpdateServerRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
|
const path = '/server-info/status'
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: '/server-info/status',
|
path,
|
||||||
value: ServerStatus.Updating,
|
value: ServerStatus.Updating,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
setTimeout(() => {
|
||||||
|
const patch = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path,
|
||||||
|
value: ServerStatus.Running,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path: '/server-info/version',
|
||||||
|
value: this.config.version + '.1',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
// quickly revert patch to proper version to prevent infinite refresh loop
|
||||||
|
const patch2 = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path: '/server-info/version',
|
||||||
|
value: this.config.version,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch: patch2 } })
|
||||||
|
}, this.revertTime)
|
||||||
|
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async restartServer (params: RR.RestartServerReq): Promise<RR.RestartServerRes> {
|
async restartServer (params: RR.RestartServerReq): Promise<RR.RestartServerRes> {
|
||||||
@@ -135,7 +162,7 @@ export class MockApiService extends ApiService {
|
|||||||
value: params.url,
|
value: params.url,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
// async setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes> {
|
// async setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes> {
|
||||||
@@ -147,14 +174,14 @@ export class MockApiService extends ApiService {
|
|||||||
// value: params.url,
|
// value: params.url,
|
||||||
// },
|
// },
|
||||||
// ]
|
// ]
|
||||||
// return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
// return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// password
|
// password
|
||||||
async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
// async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
||||||
await pauseFor(2000)
|
// await pauseFor(2000)
|
||||||
return null
|
// return null
|
||||||
}
|
// }
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
|
|
||||||
@@ -167,7 +194,7 @@ export class MockApiService extends ApiService {
|
|||||||
value: 0,
|
value: 0,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
const { revision } = await this.http.rpcRequest({ method: 'db.patch', params: { patch } }) as WithRevision<null>
|
const { revision } = await this.http.rpcRequest<WithRevision<RR.GetNotificationsRes>>({ method: 'db.patch', params: { patch } }) as WithRevision<null>
|
||||||
return {
|
return {
|
||||||
response: Mock.Notifications,
|
response: Mock.Notifications,
|
||||||
revision,
|
revision,
|
||||||
@@ -200,24 +227,28 @@ export class MockApiService extends ApiService {
|
|||||||
value: params.ssid,
|
value: params.ssid,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteWifiRaw (params: RR.DeleteWifiReq): Promise<RR.DeleteWifiRes> {
|
async deleteWifiRaw (params: RR.DeleteWifiReq): Promise<RR.DeleteWifiRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
const patch = [
|
const patch: Operation[] = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REMOVE,
|
||||||
path: '/server-info/wifi/selected',
|
path: `/server-info/wifi/ssids/${params.ssid}`,
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
op: PatchOp.REPLACE,
|
|
||||||
path: '/server-info/wifi/connected',
|
|
||||||
value: null,
|
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// op: PatchOp.REPLACE,
|
||||||
|
// path: '/server-info/wifi/selected',
|
||||||
|
// value: null,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// op: PatchOp.REPLACE,
|
||||||
|
// path: '/server-info/wifi/connected',
|
||||||
|
// value: null,
|
||||||
|
// },
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
// ssh
|
// ssh
|
||||||
@@ -241,14 +272,26 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async createBackupRaw (params: RR.CreateBackupReq): Promise<RR.CreateBackupRes> {
|
async createBackupRaw (params: RR.CreateBackupReq): Promise<RR.CreateBackupRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
|
const path = '/server-info/status'
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: '/server-info/status',
|
path,
|
||||||
value: ServerStatus.BackingUp,
|
value: ServerStatus.BackingUp,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
setTimeout(() => {
|
||||||
|
const patch = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path,
|
||||||
|
value: ServerStatus.Running,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
}, this.revertTime)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async restoreBackupRaw (params: RR.RestoreBackupReq): Promise<RR.RestoreBackupRes> {
|
async restoreBackupRaw (params: RR.RestoreBackupReq): Promise<RR.RestoreBackupRes> {
|
||||||
@@ -302,7 +345,7 @@ export class MockApiService extends ApiService {
|
|||||||
value: pkg,
|
value: pkg,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async dryUpdatePackage (params: RR.DryUpdatePackageReq): Promise<RR.DryUpdatePackageRes> {
|
async dryUpdatePackage (params: RR.DryUpdatePackageReq): Promise<RR.DryUpdatePackageRes> {
|
||||||
@@ -328,25 +371,32 @@ export class MockApiService extends ApiService {
|
|||||||
path: `/package-data/${params.id}/installed/status/configured`,
|
path: `/package-data/${params.id}/installed/status/configured`,
|
||||||
value: true,
|
value: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
op: PatchOp.REPLACE,
|
|
||||||
path: `/package-data/${params.id}/installed/status/main/status`,
|
|
||||||
value: PackageMainStatus.Running,
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async restorePackageRaw (params: RR.RestorePackageReq): Promise<RR.RestorePackageRes> {
|
async restorePackageRaw (params: RR.RestorePackageReq): Promise<RR.RestorePackageRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
|
const path = `/package-data/${params.id}/installed/status/main/status`
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/package-data/${params.id}/installed/status/main/status`,
|
path,
|
||||||
value: PackageMainStatus.Restoring,
|
value: PackageMainStatus.Restoring,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
setTimeout(() => {
|
||||||
|
const patch = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REPLACE,
|
||||||
|
path,
|
||||||
|
value: PackageMainStatus.Stopped,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
}, this.revertTime)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async executePackageAction (params: RR.ExecutePackageActionReq): Promise<RR.ExecutePackageActionRes> {
|
async executePackageAction (params: RR.ExecutePackageActionReq): Promise<RR.ExecutePackageActionRes> {
|
||||||
@@ -361,14 +411,15 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async startPackageRaw (params: RR.StartPackageReq): Promise<RR.StartPackageRes> {
|
async startPackageRaw (params: RR.StartPackageReq): Promise<RR.StartPackageRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
|
const path = `/package-data/${params.id}/installed/status/main/status`
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/package-data/${params.id}/installed/status/main/status`,
|
path,
|
||||||
value: PackageMainStatus.Running,
|
value: PackageMainStatus.Running,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
return this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}
|
}
|
||||||
|
|
||||||
async dryStopPackage (params: RR.DryStopPackageReq): Promise<RR.DryStopPackageRes> {
|
async dryStopPackage (params: RR.DryStopPackageReq): Promise<RR.DryStopPackageRes> {
|
||||||
@@ -378,10 +429,11 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async stopPackageRaw (params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
|
async stopPackageRaw (params: RR.StopPackageReq): Promise<RR.StopPackageRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
|
const path = `/package-data/${params.id}/installed/status/main/status`
|
||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/package-data/${params.id}/installed/status/main/status`,
|
path,
|
||||||
value: PackageMainStatus.Stopping,
|
value: PackageMainStatus.Stopping,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -390,12 +442,12 @@ export class MockApiService extends ApiService {
|
|||||||
const patch = [
|
const patch = [
|
||||||
{
|
{
|
||||||
op: PatchOp.REPLACE,
|
op: PatchOp.REPLACE,
|
||||||
path: `/package-data/${params.id}/installed/status/main/status`,
|
path,
|
||||||
value: PackageMainStatus.Stopped,
|
value: PackageMainStatus.Stopped,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
}, 2000)
|
}, this.revertTime)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
@@ -414,7 +466,17 @@ export class MockApiService extends ApiService {
|
|||||||
value: PackageState.Removing,
|
value: PackageState.Removing,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
return this.http.rpcRequest({ method: 'db.patch', params: { patch } })
|
const res = await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
setTimeout(async () => {
|
||||||
|
const patch = [
|
||||||
|
{
|
||||||
|
op: PatchOp.REMOVE,
|
||||||
|
path: `/package-data/${params.id}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
|
||||||
|
}, this.revertTime)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
async dryConfigureDependency (params: RR.DryConfigureDependencyReq): Promise<RR.DryConfigureDependencyRes> {
|
async dryConfigureDependency (params: RR.DryConfigureDependencyReq): Promise<RR.DryConfigureDependencyRes> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { HttpService } from '../../http.service'
|
import { HttpService, Method } from '../../http.service'
|
||||||
import { RR } from '../api.types'
|
import { RR } from '../api.types'
|
||||||
import { MarketplaceApiService } from './marketplace-api.service'
|
import { MarketplaceApiService } from './marketplace-api.service'
|
||||||
import { PatchDbService } from '../../patch-db/patch-db.service'
|
import { PatchDbService } from '../../patch-db/patch-db.service'
|
||||||
@@ -17,29 +17,55 @@ export class MarketplaceLiveApiService extends MarketplaceApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(this.getMarketplaceURL('eos'), params)
|
const url = this.getMarketplaceURL('eos')
|
||||||
|
return this.http.httpRequest<RR.GetMarketplaceEOSRes>({
|
||||||
|
method: Method.GET,
|
||||||
|
url: url + '/eos',
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
||||||
return this.http.simpleGet<RR.GetMarketplaceDataRes>(this.getMarketplaceURL('package'), params)
|
const url = this.getMarketplaceURL('package')
|
||||||
|
return this.http.httpRequest<RR.GetMarketplaceDataRes>({
|
||||||
|
method: Method.GET,
|
||||||
|
url: url + '/data',
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
||||||
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
||||||
const threadParams = {
|
return this.http.httpRequest<RR.GetMarketplacePackagesRes>({
|
||||||
...params,
|
method: Method.GET,
|
||||||
ids: JSON.stringify(params.ids),
|
url: url + '/packages',
|
||||||
}
|
params: {
|
||||||
|
...params,
|
||||||
return this.http.simpleGet<RR.GetMarketplacePackagesRes>(url, threadParams)
|
ids: JSON.stringify(params.ids),
|
||||||
|
},
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
||||||
return this.http.simpleGet<RR.GetReleaseNotesRes>(this.getMarketplaceURL('package'), params)
|
const url = this.getMarketplaceURL('package')
|
||||||
|
return this.http.httpRequest<RR.GetReleaseNotesRes>({
|
||||||
|
method: Method.GET,
|
||||||
|
url: url + + '/release-notes',
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes> {
|
async getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes> {
|
||||||
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
||||||
return this.http.simpleGet<RR.GetLatestVersionRes>(url, params)
|
return this.http.httpRequest<RR.GetLatestVersionRes>({
|
||||||
|
method: Method.GET,
|
||||||
|
url: url + '/latest-version',
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
|
|||||||
import { pauseFor } from '../../../util/misc.util'
|
import { pauseFor } from '../../../util/misc.util'
|
||||||
import { RR } from '../api.types'
|
import { RR } from '../api.types'
|
||||||
import { Mock } from '../api.fixures'
|
import { Mock } from '../api.fixures'
|
||||||
import { HttpService } from '../../http.service'
|
import { HttpService, Method } from '../../http.service'
|
||||||
import { MarketplaceApiService } from './marketplace-api.service'
|
import { MarketplaceApiService } from './marketplace-api.service'
|
||||||
import { PatchDbService } from '../../patch-db/patch-db.service'
|
import { PatchDbService } from '../../patch-db/patch-db.service'
|
||||||
import { ConfigService } from '../../config.service'
|
import { ConfigService } from '../../config.service'
|
||||||
@@ -20,53 +20,68 @@ export class MarketplaceMockApiService extends MarketplaceApiService {
|
|||||||
// marketplace
|
// marketplace
|
||||||
|
|
||||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||||
let url = this.getMarketplaceURL('eos')
|
const url = this.getMarketplaceURL('eos')
|
||||||
if (this.useLocal(url)) {
|
if (this.useLocal(url)) {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return Mock.MarketplaceEos
|
return Mock.MarketplaceEos
|
||||||
}
|
}
|
||||||
url = `${url}/sys/version/eos`
|
return this.http.httpRequest<RR.GetMarketplaceEOSRes>({
|
||||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(url)
|
method: Method.GET,
|
||||||
|
url: `${url}/eos`,
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
||||||
let url = this.getMarketplaceURL('package')
|
const url = this.getMarketplaceURL('package')
|
||||||
if (this.useLocal(url)) {
|
if (this.useLocal(url)) {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return {
|
return {
|
||||||
categories: ['featured', 'bitcoin', 'lightning', 'data', 'messaging', 'social', 'alt coin'],
|
categories: ['featured', 'bitcoin', 'lightning', 'data', 'messaging', 'social', 'alt coin'],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
url = `${url}/data`
|
return this.http.httpRequest<RR.GetMarketplaceDataRes>({
|
||||||
return this.http.simpleGet<RR.GetMarketplaceDataRes>(url)
|
method: Method.GET,
|
||||||
|
url: `${url}/data`,
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
||||||
let url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
||||||
const threadParams = {
|
|
||||||
...params,
|
|
||||||
ids: JSON.stringify(params.ids),
|
|
||||||
}
|
|
||||||
if (this.useLocal(url)) {
|
if (this.useLocal(url)) {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return Mock.AvailableList
|
return Mock.MarketplacePkgsList
|
||||||
}
|
}
|
||||||
url = `${url}/packages`
|
return this.http.httpRequest<RR.GetMarketplacePackagesRes>({
|
||||||
return this.http.simpleGet<RR.GetMarketplacePackagesRes>(url, threadParams)
|
method: Method.GET,
|
||||||
|
url: `${url}/packages`,
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
ids: JSON.stringify(params.ids),
|
||||||
|
},
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
||||||
let url = this.getMarketplaceURL('package')
|
const url = this.getMarketplaceURL('package')
|
||||||
if (this.useLocal(url)) {
|
if (this.useLocal(url)) {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return Mock.ReleaseNotes
|
return Mock.ReleaseNotes
|
||||||
}
|
}
|
||||||
url = `${url}/release-notes`
|
return this.http.httpRequest<RR.GetReleaseNotesRes>({
|
||||||
return this.http.simpleGet<RR.GetReleaseNotesRes>(url, params)
|
method: Method.GET,
|
||||||
|
url: `${url}/release-notes`,
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes> {
|
async getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes> {
|
||||||
let url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
const url = this.getMarketplaceURL('package', params.ids?.length > 1)
|
||||||
if (this.useLocal(url)) {
|
if (this.useLocal(url)) {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return params.ids.reduce((obj, id) => {
|
return params.ids.reduce((obj, id) => {
|
||||||
@@ -74,8 +89,13 @@ export class MarketplaceMockApiService extends MarketplaceApiService {
|
|||||||
return obj
|
return obj
|
||||||
}, { })
|
}, { })
|
||||||
}
|
}
|
||||||
url = `${url}/latest-version`
|
|
||||||
return this.http.simpleGet<RR.GetLatestVersionRes>(url)
|
return this.http.httpRequest<RR.GetLatestVersionRes>({
|
||||||
|
method: Method.GET,
|
||||||
|
url: `${url}/latest-version`,
|
||||||
|
params,
|
||||||
|
withCredentials: false,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private useLocal (url: string): boolean {
|
private useLocal (url: string): boolean {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class ConnectionService {
|
|||||||
|
|
||||||
combineLatest([this.networkState$.pipe(distinctUntilChanged()), this.patch.watchConnection$().pipe(distinctUntilChanged())])
|
combineLatest([this.networkState$.pipe(distinctUntilChanged()), this.patch.watchConnection$().pipe(distinctUntilChanged())])
|
||||||
.subscribe(async ([network, connectionStatus]) => {
|
.subscribe(async ([network, connectionStatus]) => {
|
||||||
const addrs = this.patch.data['server-info']?.['connection-addresses']
|
const addrs = this.patch.data['server-info']['connection-addresses']
|
||||||
if (connectionStatus !== ConnectionStatus.Disconnected) {
|
if (connectionStatus !== ConnectionStatus.Disconnected) {
|
||||||
this.connectionFailure$.next(ConnectionFailure.None)
|
this.connectionFailure$.next(ConnectionFailure.None)
|
||||||
} else if (!network) {
|
} else if (!network) {
|
||||||
@@ -42,12 +42,12 @@ export class ConnectionService {
|
|||||||
} else {
|
} else {
|
||||||
// diagnosing
|
// diagnosing
|
||||||
this.connectionFailure$.next(ConnectionFailure.Diagnosing)
|
this.connectionFailure$.next(ConnectionFailure.Diagnosing)
|
||||||
const torSuccess = await this.testAddrs(addrs?.tor || [])
|
const torSuccess = await this.testAddrs(addrs.tor)
|
||||||
if (torSuccess) {
|
if (torSuccess) {
|
||||||
// TOR SUCCESS, EMBASSY IS PROBLEM
|
// TOR SUCCESS, EMBASSY IS PROBLEM
|
||||||
this.connectionFailure$.next(ConnectionFailure.Embassy)
|
this.connectionFailure$.next(ConnectionFailure.Embassy)
|
||||||
} else {
|
} else {
|
||||||
const clearnetSuccess = await this.testAddrs(addrs?.clearnet || [])
|
const clearnetSuccess = await this.testAddrs(addrs.clearnet)
|
||||||
if (clearnetSuccess) {
|
if (clearnetSuccess) {
|
||||||
// CLEARNET SUCCESS, TOR IS PROBLEM
|
// CLEARNET SUCCESS, TOR IS PROBLEM
|
||||||
this.connectionFailure$.next(ConnectionFailure.Tor)
|
this.connectionFailure$.next(ConnectionFailure.Tor)
|
||||||
@@ -76,6 +76,7 @@ export class ConnectionService {
|
|||||||
await this.httpService.httpRequest({
|
await this.httpService.httpRequest({
|
||||||
method: Method.GET,
|
method: Method.GET,
|
||||||
url: addr,
|
url: addr,
|
||||||
|
withCredentials: false,
|
||||||
})
|
})
|
||||||
return true
|
return true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { Revision } from 'patch-db-client'
|
|||||||
})
|
})
|
||||||
export class HttpService {
|
export class HttpService {
|
||||||
private unauthorizedApiResponse$ = new Subject()
|
private unauthorizedApiResponse$ = new Subject()
|
||||||
authReqEnabled: boolean = false
|
|
||||||
fullUrl: string
|
fullUrl: string
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
@@ -44,22 +43,15 @@ export class HttpService {
|
|||||||
if (isRpcSuccess(res)) return res.result
|
if (isRpcSuccess(res)) return res.result
|
||||||
}
|
}
|
||||||
|
|
||||||
async simpleGet<T> (url: string, params: { [param: string]: string | string[] } = { }): Promise<T> {
|
|
||||||
Object.keys(params).forEach(key => {
|
|
||||||
if (!params[key]) delete params[key]
|
|
||||||
})
|
|
||||||
return this.http.get<T>(url, { params }).toPromise()
|
|
||||||
}
|
|
||||||
|
|
||||||
async httpRequest<T> (httpOpts: HttpOptions): Promise<T> {
|
async httpRequest<T> (httpOpts: HttpOptions): Promise<T> {
|
||||||
let { body, timeout, ...rest} = this.translateOptions(httpOpts)
|
let { body, timeout, url, ...rest} = this.translateOptions(httpOpts)
|
||||||
let req: Observable<{ body: T }>
|
let req: Observable<{ body: T }>
|
||||||
switch (httpOpts.method){
|
switch (httpOpts.method){
|
||||||
case Method.GET: req = this.http.get(this.fullUrl, rest) as any; break
|
case Method.GET: req = this.http.get(url, rest) as any; break
|
||||||
case Method.POST: req = this.http.post(this.fullUrl, body, rest) as any; break
|
case Method.POST: req = this.http.post(url, body, rest) as any; break
|
||||||
case Method.PUT: req = this.http.put(this.fullUrl, body, rest) as any; break
|
case Method.PUT: req = this.http.put(url, body, rest) as any; break
|
||||||
case Method.PATCH: req = this.http.patch(this.fullUrl, body, rest) as any; break
|
case Method.PATCH: req = this.http.patch(url, body, rest) as any; break
|
||||||
case Method.DELETE: req = this.http.delete(this.fullUrl, rest) as any; break
|
case Method.DELETE: req = this.http.delete(url, rest) as any; break
|
||||||
}
|
}
|
||||||
|
|
||||||
return (timeout ? withTimeout(req, timeout) : req)
|
return (timeout ? withTimeout(req, timeout) : req)
|
||||||
@@ -68,16 +60,25 @@ export class HttpService {
|
|||||||
.catch(e => { throw new HttpError(e) })
|
.catch(e => { throw new HttpError(e) })
|
||||||
}
|
}
|
||||||
|
|
||||||
translateOptions (httpOpts: HttpOptions): HttpJsonOptions {
|
private translateOptions (httpOpts: HttpOptions): HttpJsonOptions {
|
||||||
|
if (httpOpts.withCredentials !== false) {
|
||||||
|
httpOpts.withCredentials = this.config.mocks.enabled ? false : true
|
||||||
|
}
|
||||||
|
|
||||||
|
const urlIsRelative = !httpOpts.url || httpOpts.url.startsWith('/')
|
||||||
|
const url = urlIsRelative ?
|
||||||
|
this.fullUrl + httpOpts.url :
|
||||||
|
httpOpts.url
|
||||||
|
|
||||||
return {
|
return {
|
||||||
observe: 'events',
|
observe: 'events',
|
||||||
responseType: 'json',
|
responseType: 'json',
|
||||||
reportProgress: false,
|
reportProgress: false,
|
||||||
withCredentials: this.config.mocks.enabled ? false : true,
|
withCredentials: httpOpts.withCredentials,
|
||||||
headers: httpOpts.headers,
|
headers: httpOpts.headers,
|
||||||
params: httpOpts.params,
|
params: httpOpts.params,
|
||||||
body: httpOpts.data || { },
|
body: httpOpts.data || { },
|
||||||
url: httpOpts.url,
|
url,
|
||||||
timeout: httpOpts.readTimeout,
|
timeout: httpOpts.readTimeout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export enum ConnectionStatus {
|
|||||||
})
|
})
|
||||||
export class PatchDbService {
|
export class PatchDbService {
|
||||||
connectionStatus$ = new BehaviorSubject(ConnectionStatus.Initializing)
|
connectionStatus$ = new BehaviorSubject(ConnectionStatus.Initializing)
|
||||||
sequence$: Observable<number>
|
|
||||||
data: DataModel
|
data: DataModel
|
||||||
private patchDb: PatchDB<DataModel>
|
private patchDb: PatchDB<DataModel>
|
||||||
private patchSub: Subscription
|
private patchSub: Subscription
|
||||||
@@ -33,10 +32,7 @@ export class PatchDbService {
|
|||||||
|
|
||||||
async init (): Promise<void> {
|
async init (): Promise<void> {
|
||||||
const cache = await this.bootstrapper.init()
|
const cache = await this.bootstrapper.init()
|
||||||
console.log('CACHECACHE', cache)
|
|
||||||
this.patchDb = new PatchDB([this.source, this.http], this.http, cache)
|
this.patchDb = new PatchDB([this.source, this.http], this.http, cache)
|
||||||
|
|
||||||
this.sequence$ = this.patchDb.store.sequence$.asObservable()
|
|
||||||
this.data = this.patchDb.store.cache.data
|
this.data = this.patchDb.store.cache.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ export class StartupAlertsService {
|
|||||||
private readonly wizardBaker: WizardBaker,
|
private readonly wizardBaker: WizardBaker,
|
||||||
private readonly patch: PatchDbService,
|
private readonly patch: PatchDbService,
|
||||||
) {
|
) {
|
||||||
const welcome: Check<boolean> = {
|
const osWelcome: Check<boolean> = {
|
||||||
name: 'welcome',
|
name: 'osWelcome',
|
||||||
shouldRun: () => this.shouldRunOsWelcome(),
|
shouldRun: () => this.shouldRunOsWelcome(),
|
||||||
check: async () => true,
|
check: async () => true,
|
||||||
display: () => this.displayOsWelcome(),
|
display: () => this.displayOsWelcome(),
|
||||||
@@ -42,14 +42,14 @@ export class StartupAlertsService {
|
|||||||
display: pkg => this.displayOsUpdateCheck(pkg),
|
display: pkg => this.displayOsUpdateCheck(pkg),
|
||||||
hasRun: this.config.skipStartupAlerts,
|
hasRun: this.config.skipStartupAlerts,
|
||||||
}
|
}
|
||||||
const apps: Check<boolean> = {
|
const pkgsUpdate: Check<boolean> = {
|
||||||
name: 'apps',
|
name: 'pkgsUpdate',
|
||||||
shouldRun: () => this.shouldRunAppsCheck(),
|
shouldRun: () => this.shouldRunAppsCheck(),
|
||||||
check: () => this.appsCheck(),
|
check: () => this.appsCheck(),
|
||||||
display: () => this.displayAppsCheck(),
|
display: () => this.displayAppsCheck(),
|
||||||
hasRun: this.config.skipStartupAlerts,
|
hasRun: this.config.skipStartupAlerts,
|
||||||
}
|
}
|
||||||
this.checks = [welcome, osUpdate, apps]
|
this.checks = [osWelcome, osUpdate, pkgsUpdate]
|
||||||
}
|
}
|
||||||
|
|
||||||
// This takes our three checks and filters down to those that should run.
|
// This takes our three checks and filters down to those that should run.
|
||||||
@@ -79,8 +79,7 @@ export class StartupAlertsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private shouldRunOsWelcome (): boolean {
|
private shouldRunOsWelcome (): boolean {
|
||||||
const data = this.patch.data
|
return this.patch.data.ui['welcome-ack'] !== this.config.version
|
||||||
return !data.ui['welcome-ack'] && data['server-info'].version === this.config.version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldRunOsUpdateCheck (): boolean {
|
private shouldRunOsUpdateCheck (): boolean {
|
||||||
@@ -94,7 +93,7 @@ export class StartupAlertsService {
|
|||||||
private async osUpdateCheck (): Promise<RR.GetMarketplaceEOSRes | undefined> {
|
private async osUpdateCheck (): Promise<RR.GetMarketplaceEOSRes | undefined> {
|
||||||
const res = await this.marketplaceApi.getEos({ })
|
const res = await this.marketplaceApi.getEos({ })
|
||||||
|
|
||||||
if (this.emver.compare(this.patch.data['server-info'].version, res.version) === -1) {
|
if (this.emver.compare(this.config.version, res.version) === -1) {
|
||||||
return res
|
return res
|
||||||
} else {
|
} else {
|
||||||
return undefined
|
return undefined
|
||||||
@@ -113,7 +112,7 @@ export class StartupAlertsService {
|
|||||||
component: OSWelcomePage,
|
component: OSWelcomePage,
|
||||||
presentingElement: await this.modalCtrl.getTop(),
|
presentingElement: await this.modalCtrl.getTop(),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
version: this.patch.data['server-info'].version,
|
version: this.config.version,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user