Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/uhk-agent/src/electron-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async function createWindow() {

setMenu(win, options.devtools);
deviceService = new DeviceService(logger, win, uhkHidDeviceService, uhkOperations, options, packagesDir);
appUpdateService = new AppUpdateService(logger, win, app);
appUpdateService = new AppUpdateService(logger, win, options);
appService = new AppService(logger, win, deviceService, options, packagesDir);
sudoService = new SudoService(logger, options, deviceService, packagesDir);
// and load the index.html of the app.
Expand Down
34 changes: 27 additions & 7 deletions packages/uhk-agent/src/services/app-update.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ import { autoUpdater } from 'electron-updater';
import { UpdateInfo, ProgressInfo } from 'builder-util-runtime';
import isDev from 'electron-is-dev';
import storage from 'electron-settings';

import { ApplicationSettings, IpcEvents, LogService } from 'uhk-common';
import { inspect } from 'node:util';

import {
ApplicationSettings,
CommandLineArgs,
ERR_UPDATER_INVALID_SIGNATURE,
IpcEvents,
LogService,
} from 'uhk-common';
import { MainServiceBase } from './main-service-base';
import { getUpdaterLoggerService } from '../util';

Expand All @@ -16,13 +23,20 @@ export class AppUpdateService extends MainServiceBase {

constructor(protected logService: LogService,
protected win: Electron.BrowserWindow,
private app: Electron.App) {
private options: CommandLineArgs) {
super(logService, win);

autoUpdater.logger = getUpdaterLoggerService(logService);

this.initListeners();
logService.misc('[AppUpdateService] init success');

if (options['simulate-invalid-codesign-signature']) {
logService.misc('[AppUpdateService] init simulate invalid codesign timer');
setTimeout(() => {
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateError, ERR_UPDATER_INVALID_SIGNATURE);
}, 10000)
}
}

private initListeners() {
Expand All @@ -44,11 +58,17 @@ export class AppUpdateService extends MainServiceBase {
}
});

autoUpdater.on('error', (ev: any, err: string) => {
this.logService.error('[AppUpdateService] error', err);
autoUpdater.on('error', (error: Error, message: string) => {
this.logService.error('[AppUpdateService] error', inspect(error));
this.logService.error('[AppUpdateService] error message', message);
if ((error as NodeJS.ErrnoException)?.code === ERR_UPDATER_INVALID_SIGNATURE) {
this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateError, ERR_UPDATER_INVALID_SIGNATURE);
return
}

let msg = 'Electron updater error';
if (err) {
msg = err.substr(0, 100);
if (message) {
msg = message.substring(0, 100);
}

this.sendIpcToWindow(IpcEvents.autoUpdater.autoUpdateError, msg);
Expand Down
6 changes: 6 additions & 0 deletions packages/uhk-agent/src/util/command-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const optionDefinitions: commandLineArgs.OptionDefinition[] = [
{ name: 'reenumerate-and-exit', type: String },
{ name: 'report-id', type: Number },
{ name: 'serial-number', type: String },
{ name: 'simulate-invalid-codesign-signature', type: Boolean },
{ name: 'spe', type: Boolean }, // simulate privilege escalation error
{ name: 'usb-interface', type: Number },
{ name: 'usb-non-blocking', type: Boolean },
Expand Down Expand Up @@ -120,6 +121,11 @@ const sections: commandLineUsage.Section[] = [
description: 'Use the specified USB device that serial-number is matching.',
type: String
},
{
name: 'simulate-invalid-codesign-signature',
description: 'Agent shows the invalid code sign signature error 10 seconds after start',
type: Boolean
},
{
name: 'spe',
description: 'Simulate privilege escalation error',
Expand Down
5 changes: 5 additions & 0 deletions packages/uhk-common/src/models/command-line-args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ export interface CommandLineArgs extends DeviceIdentifier {
* Report Id that used for USB communication
*/
'report-id'?: number;

/**
* Agent shows the invalid code sign signature error 10 seconds after start
*/
'simulate-invalid-codesign-signature'?: boolean;
/**
* simulate privilege escalation error
*/
Expand Down
1 change: 1 addition & 0 deletions packages/uhk-common/src/util/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export namespace Constants {
}

export const UHK_EEPROM_SIZE = 32768;
export const ERR_UPDATER_INVALID_SIGNATURE = 'ERR_UPDATER_INVALID_SIGNATURE'
15 changes: 15 additions & 0 deletions packages/uhk-web/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,18 @@
<out-of-space-warning *ngIf="outOfSpaceWarning.show"
[@showOutOfSpaceWarning]
[state]="outOfSpaceWarning"></out-of-space-warning>
<ng-template #manuallyUpdateNotification>
<p class="notifier__notification-message">
Agent's digital signature has changed. Please <a href="https://uhk.io/agent" class="alert-link" externalUrl>update it manually</a> this time. Agent will auto-update afterward.
</p>
<button
class="notifier__notification-button"
type="button"
title="dismiss"
(click)="dismissUpdateErrorNotification()"
>
<svg class="notifier__notification-button-icon" viewBox="0 0 24 24" width="20" height="20">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
</svg>
</button>
</ng-template>
28 changes: 27 additions & 1 deletion packages/uhk-web/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Component, HostListener, OnDestroy, ChangeDetectorRef, ViewChild } from '@angular/core';
import { ActivatedRoute, Event, NavigationEnd, Router } from '@angular/router';
import { animate, style, transition, trigger } from '@angular/animations';
import { NotifierService } from '@ert78gb/angular-notifier';
import { faPuzzlePiece, faArrowUp } from '@fortawesome/free-solid-svg-icons';
import { Actions, ofType } from '@ngrx/effects';
import { SplitGutterInteractionEvent } from 'angular-split';
import { Observable, Subscription } from 'rxjs';
import { Action, Store } from '@ngrx/store';
import { ERR_UPDATER_INVALID_SIGNATURE } from 'uhk-common';

import { ActionTypes as AppUpdateActionTypes } from './store/actions/app-update.action';
import { DoNotUpdateAppAction, UpdateAppAction } from './store/actions/app-update.action';
import { EnableUsbStackTestAction, UpdateFirmwareAction } from './store/actions/device';
import {
Expand Down Expand Up @@ -102,6 +106,7 @@ import { SecondSideMenuContainerComponent } from './components/side-menu';
})
export class MainAppComponent implements OnDestroy {
@ViewChild(SecondSideMenuContainerComponent) secondarySideMenuContainer: SecondSideMenuContainerComponent;
@ViewChild('manuallyUpdateNotification', { static: true }) manuallyUpdateNotificationTmpl;

donglePairingState: DonglePairingState;
newPairedDevicesState: BleAddingState;
Expand All @@ -120,6 +125,7 @@ export class MainAppComponent implements OnDestroy {
bottom: 0
};
statusBuffer: string;
private actionsSubscription: Subscription;
private donglePairingStateSubscription: Subscription;
private newPairedDevicesStateSubscription: Subscription;
private errorPanelHeightSubscription: Subscription;
Expand All @@ -136,7 +142,22 @@ export class MainAppComponent implements OnDestroy {
constructor(private store: Store<AppState>,
private route: ActivatedRoute,
private router: Router,
private cdRef: ChangeDetectorRef) {
private cdRef: ChangeDetectorRef,
private actions$: Actions,
private notificationService: NotifierService,
) {
this.actionsSubscription = actions$.pipe(
ofType(AppUpdateActionTypes.InvalidCodesignSignature)
)
.subscribe(() => {
notificationService.show({
message: '',
type: 'info',
template: this.manuallyUpdateNotificationTmpl,
id: ERR_UPDATER_INVALID_SIGNATURE,
})
})

this.donglePairingStateSubscription = store.select(getDonglePairingState)
.subscribe(data => {
this.donglePairingState = data;
Expand Down Expand Up @@ -211,6 +232,7 @@ export class MainAppComponent implements OnDestroy {
}

ngOnDestroy(): void {
this.actionsSubscription.unsubscribe();
this.donglePairingStateSubscription.unsubscribe();
this.newPairedDevicesStateSubscription.unsubscribe();
this.errorPanelHeightSubscription.unsubscribe();
Expand Down Expand Up @@ -263,6 +285,10 @@ export class MainAppComponent implements OnDestroy {
this.store.dispatch(new CloseErrorPanelAction());
}

dismissUpdateErrorNotification(): void {
this.notificationService.hide(ERR_UPDATER_INVALID_SIGNATURE);
}

showErrorPanel(): void {
this.store.dispatch(new ShowErrorPanelAction());
}
Expand Down
6 changes: 6 additions & 0 deletions packages/uhk-web/src/app/store/actions/app-update.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { UpdateInfo } from '../../models/update-info';

export enum ActionTypes {
ForceUpdate = '[app-update] force update',
InvalidCodesignSignature = '[app-update] invalid codesign signature',
UpdateAvailable = '[app-update] update available',
UpdateApp = '[app-update] update app',
DoNotUpdateApp = '[app-update] do not update app',
Expand All @@ -16,6 +17,10 @@ export class ForceUpdateAction implements Action {
type = ActionTypes.ForceUpdate;
}

export class InvalidCodesignSignatureAction implements Action {
type = ActionTypes.InvalidCodesignSignature;
}

export class UpdateAvailableAction implements Action {
type = ActionTypes.UpdateAvailable;
}
Expand Down Expand Up @@ -48,6 +53,7 @@ export class UpdateErrorAction implements Action {

export type Actions
= UpdateAvailableAction
| InvalidCodesignSignatureAction
| UpdateAppAction
| DoNotUpdateAppAction
| UpdateDownloadedAction
Expand Down
7 changes: 6 additions & 1 deletion packages/uhk-web/src/app/store/effects/app-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { Actions, createEffect, ofType } from '@ngrx/effects';
import { EMPTY } from 'rxjs';
import { first, map, tap, withLatestFrom } from 'rxjs/operators';

import { LogService, NotificationType } from 'uhk-common';
import { ERR_UPDATER_INVALID_SIGNATURE, LogService, NotificationType } from 'uhk-common';

import {
ActionTypes,
ForceUpdateAction,
InvalidCodesignSignatureAction,
UpdateAppAction,
UpdateAvailableAction,
UpdateErrorAction
Expand Down Expand Up @@ -74,6 +75,10 @@ export class AppUpdateEffect {
ofType<UpdateErrorAction>(ActionTypes.UpdateError),
map(action => action.payload),
map((message: string) => {
if (message === ERR_UPDATER_INVALID_SIGNATURE) {
return new InvalidCodesignSignatureAction();
}

return new ShowNotificationAction({
type: NotificationType.Error,
message
Expand Down
4 changes: 4 additions & 0 deletions packages/uhk-web/src/styles/_global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,7 @@ mwl-confirmation-popover-window {
cursor: not-allowed;
}
}

.alert-link {
text-decoration: underline;
}