mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
feat: enable strictNullChecks
feat: enable `noImplicitAny` chore: remove sync data access fix loading package data for affected dependencies chore: properly get alt marketplace data update patchdb client to allow for emit on undefined values
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { Component, Input, ViewChild } from '@angular/core'
|
||||
import { IonInput, ModalController } from '@ionic/angular'
|
||||
import { DiskInfo, CifsBackupTarget, DiskBackupTarget } from 'src/app/services/api/api.service'
|
||||
import {
|
||||
DiskInfo,
|
||||
CifsBackupTarget,
|
||||
DiskBackupTarget,
|
||||
} from 'src/app/services/api/api.service'
|
||||
import * as argon2 from '@start9labs/argon2'
|
||||
|
||||
@Component({
|
||||
@@ -21,26 +25,27 @@ export class PasswordPage {
|
||||
passwordVer = ''
|
||||
unmasked2 = false
|
||||
|
||||
constructor (
|
||||
private modalController: ModalController,
|
||||
) { }
|
||||
constructor(private modalController: ModalController) {}
|
||||
|
||||
ngAfterViewInit () {
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => this.elem.setFocus(), 400)
|
||||
}
|
||||
|
||||
async verifyPw () {
|
||||
if (!this.target || !this.target['embassy-os']) this.pwError = 'No recovery target' // unreachable
|
||||
async verifyPw() {
|
||||
if (!this.target || !this.target['embassy-os'])
|
||||
this.pwError = 'No recovery target' // unreachable
|
||||
|
||||
try {
|
||||
argon2.verify(this.target['embassy-os']['password-hash'], this.password)
|
||||
const passwordHash = this.target['embassy-os']?.['password-hash'] || ''
|
||||
|
||||
argon2.verify(passwordHash, this.password)
|
||||
this.modalController.dismiss({ password: this.password }, 'success')
|
||||
} catch (e) {
|
||||
this.pwError = 'Incorrect password provided'
|
||||
}
|
||||
}
|
||||
|
||||
async submitPw () {
|
||||
async submitPw() {
|
||||
this.validate()
|
||||
if (this.password !== this.passwordVer) {
|
||||
this.verError = '*passwords do not match'
|
||||
@@ -50,8 +55,8 @@ export class PasswordPage {
|
||||
this.modalController.dismiss({ password: this.password }, 'success')
|
||||
}
|
||||
|
||||
validate () {
|
||||
if (!!this.target) return this.pwError = ''
|
||||
validate() {
|
||||
if (!!this.target) return (this.pwError = '')
|
||||
|
||||
if (this.passwordVer) {
|
||||
this.checkVer()
|
||||
@@ -64,11 +69,12 @@ export class PasswordPage {
|
||||
}
|
||||
}
|
||||
|
||||
checkVer () {
|
||||
this.verError = this.password !== this.passwordVer ? 'Passwords do not match' : ''
|
||||
checkVer() {
|
||||
this.verError =
|
||||
this.password !== this.passwordVer ? 'Passwords do not match' : ''
|
||||
}
|
||||
|
||||
cancel () {
|
||||
cancel() {
|
||||
this.modalController.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,19 @@ export class ProdKeyModal {
|
||||
productKey = ''
|
||||
unmasked = false
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly modalController: ModalController,
|
||||
private readonly apiService: ApiService,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly httpService: HttpService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngAfterViewInit () {
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => this.elem.setFocus(), 400)
|
||||
}
|
||||
|
||||
async verifyProductKey () {
|
||||
if (!this.productKey) return
|
||||
async verifyProductKey() {
|
||||
if (!this.productKey || !this.target.logicalname) return
|
||||
|
||||
const loader = await this.loadingCtrl.create({
|
||||
message: 'Verifying Product Key',
|
||||
@@ -48,7 +48,7 @@ export class ProdKeyModal {
|
||||
}
|
||||
}
|
||||
|
||||
cancel () {
|
||||
cancel() {
|
||||
this.modalController.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ export class RecoverPage {
|
||||
'embassy-os': p['embassy-os'],
|
||||
}
|
||||
this.mappedDrives.push({
|
||||
hasValidBackup: p['embassy-os']?.full,
|
||||
is02x: drive['embassy-os']?.version.startsWith('0.2'),
|
||||
hasValidBackup: !!p['embassy-os']?.full,
|
||||
is02x: !!drive['embassy-os']?.version.startsWith('0.2'),
|
||||
drive,
|
||||
})
|
||||
})
|
||||
@@ -111,7 +111,8 @@ export class RecoverPage {
|
||||
{
|
||||
text: 'Use Drive',
|
||||
handler: async () => {
|
||||
await this.importDrive(importableDrive.guid)
|
||||
if (importableDrive.guid)
|
||||
await this.importDrive(importableDrive.guid)
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -148,11 +149,14 @@ export class RecoverPage {
|
||||
}
|
||||
|
||||
async select(target: DiskBackupTarget) {
|
||||
const is02x = target['embassy-os'].version.startsWith('0.2')
|
||||
const is02x = target['embassy-os']?.version.startsWith('0.2')
|
||||
const { logicalname } = target
|
||||
|
||||
if (!logicalname) return
|
||||
|
||||
if (this.stateService.hasProductKey) {
|
||||
if (is02x) {
|
||||
this.selectRecoverySource(target.logicalname)
|
||||
this.selectRecoverySource(logicalname)
|
||||
} else {
|
||||
const modal = await this.modalController.create({
|
||||
component: PasswordPage,
|
||||
@@ -160,8 +164,8 @@ export class RecoverPage {
|
||||
cssClass: 'alertlike-modal',
|
||||
})
|
||||
modal.onDidDismiss().then(res => {
|
||||
if (res.data && res.data.password) {
|
||||
this.selectRecoverySource(target.logicalname, res.data.password)
|
||||
if (res.data?.password) {
|
||||
this.selectRecoverySource(logicalname, res.data.password)
|
||||
}
|
||||
})
|
||||
await modal.present()
|
||||
@@ -188,8 +192,8 @@ export class RecoverPage {
|
||||
cssClass: 'alertlike-modal',
|
||||
})
|
||||
modal.onDidDismiss().then(res => {
|
||||
if (res.data && res.data.productKey) {
|
||||
this.selectRecoverySource(target.logicalname)
|
||||
if (res.data?.productKey) {
|
||||
this.selectRecoverySource(logicalname)
|
||||
}
|
||||
})
|
||||
await modal.present()
|
||||
|
||||
@@ -24,7 +24,7 @@ export class SuccessPage {
|
||||
await this.stateService.completeEmbassy()
|
||||
document
|
||||
.getElementById('install-cert')
|
||||
.setAttribute(
|
||||
?.setAttribute(
|
||||
'href',
|
||||
'data:application/x-x509-ca-cert;base64,' +
|
||||
encodeURIComponent(this.stateService.cert),
|
||||
@@ -56,20 +56,24 @@ export class SuccessPage {
|
||||
}
|
||||
|
||||
installCert() {
|
||||
document.getElementById('install-cert').click()
|
||||
document.getElementById('install-cert')?.click()
|
||||
}
|
||||
|
||||
download() {
|
||||
document.getElementById('tor-addr').innerHTML = this.stateService.torAddress
|
||||
document.getElementById('lan-addr').innerHTML = this.stateService.lanAddress
|
||||
const torAddress = document.getElementById('tor-addr')
|
||||
const lanAddress = document.getElementById('lan-addr')
|
||||
|
||||
if (torAddress) torAddress.innerHTML = this.stateService.torAddress
|
||||
if (lanAddress) lanAddress.innerHTML = this.stateService.lanAddress
|
||||
|
||||
document
|
||||
.getElementById('cert')
|
||||
.setAttribute(
|
||||
?.setAttribute(
|
||||
'href',
|
||||
'data:application/x-x509-ca-cert;base64,' +
|
||||
encodeURIComponent(this.stateService.cert),
|
||||
)
|
||||
let html = document.getElementById('downloadable').innerHTML
|
||||
let html = document.getElementById('downloadable')?.innerHTML || ''
|
||||
const filename = 'embassy-info.html'
|
||||
|
||||
const elem = document.createElement('a')
|
||||
|
||||
@@ -15,7 +15,7 @@ import { HttpError, RpcError } from '@start9labs/shared'
|
||||
})
|
||||
export class HttpService {
|
||||
fullUrl: string
|
||||
productKey: string
|
||||
productKey?: string
|
||||
|
||||
constructor(private readonly http: HttpClient) {
|
||||
const port = window.location.port
|
||||
@@ -43,6 +43,8 @@ export class HttpService {
|
||||
}
|
||||
|
||||
if (isRpcSuccess(res)) return res.result
|
||||
|
||||
throw new Error('Unknown RPC response')
|
||||
}
|
||||
|
||||
async encryptedHttpRequest<T>(httpOpts: {
|
||||
@@ -53,7 +55,7 @@ export class HttpService {
|
||||
const url = urlIsRelative ? this.fullUrl + httpOpts.url : httpOpts.url
|
||||
|
||||
const encryptedBody = await AES_CTR.encryptPbkdf2(
|
||||
this.productKey,
|
||||
this.productKey || '',
|
||||
encodeUtf8(JSON.stringify(httpOpts.body)),
|
||||
)
|
||||
const options = {
|
||||
@@ -74,7 +76,7 @@ export class HttpService {
|
||||
.toPromise()
|
||||
.then(res =>
|
||||
AES_CTR.decryptPbkdf2(
|
||||
this.productKey,
|
||||
this.productKey || '',
|
||||
(res as any).body as ArrayBuffer,
|
||||
),
|
||||
)
|
||||
@@ -206,7 +208,7 @@ type AES_CTR = {
|
||||
secretKey: string,
|
||||
messageBuffer: Uint8Array,
|
||||
) => Promise<Uint8Array>
|
||||
decryptPbkdf2: (secretKey, arr: ArrayBuffer) => Promise<string>
|
||||
decryptPbkdf2: (secretKey: string, arr: ArrayBuffer) => Promise<string>
|
||||
}
|
||||
|
||||
export const AES_CTR: AES_CTR = {
|
||||
@@ -243,8 +245,10 @@ export const AES_CTR: AES_CTR = {
|
||||
|
||||
export const encode16 = (buffer: Uint8Array) =>
|
||||
buffer.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '')
|
||||
export const decode16 = hexString =>
|
||||
new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)))
|
||||
export const decode16 = (hexString: string) =>
|
||||
new Uint8Array(
|
||||
hexString.match(/.{1,2}/g)?.map(byte => parseInt(byte, 16)) || [],
|
||||
)
|
||||
|
||||
export function encodeUtf8(str: string): Uint8Array {
|
||||
const encoder = new TextEncoder()
|
||||
|
||||
@@ -43,7 +43,7 @@ export class LiveApiService extends ApiService {
|
||||
)
|
||||
}
|
||||
|
||||
async set02XDrive(logicalname) {
|
||||
async set02XDrive(logicalname: string) {
|
||||
return this.http.rpcRequest<void>(
|
||||
{
|
||||
method: 'setup.recovery.v2.set',
|
||||
@@ -124,7 +124,7 @@ export class LiveApiService extends ApiService {
|
||||
}
|
||||
|
||||
function isCifsSource(
|
||||
source: CifsRecoverySource | DiskRecoverySource | undefined,
|
||||
source: CifsRecoverySource | DiskRecoverySource | null,
|
||||
): source is CifsRecoverySource {
|
||||
return !!(source as CifsRecoverySource)?.hostname
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ export class StateService {
|
||||
embassyLoaded = false
|
||||
|
||||
recoverySource: CifsRecoverySource | DiskRecoverySource
|
||||
recoveryPassword: string
|
||||
recoveryPassword?: string
|
||||
|
||||
dataTransferProgress: {
|
||||
bytesTransferred: number
|
||||
|
||||
Reference in New Issue
Block a user