diff --git a/src/app/_pgp/pgp-key-store.ts b/src/app/_pgp/pgp-key-store.ts index f1b1e22..b3ab744 100644 --- a/src/app/_pgp/pgp-key-store.ts +++ b/src/app/_pgp/pgp-key-store.ts @@ -1,7 +1,6 @@ import { KeyStore } from 'cic-client-meta'; -// const openpgp = require('openpgp'); //TODO should we put this on the mutalble key store object +// TODO should we put this on the mutalble key store object import * as openpgp from 'openpgp'; -import {throwError} from 'rxjs'; const keyring = new openpgp.Keyring(); interface MutableKeyStore extends KeyStore { @@ -16,6 +15,7 @@ interface MutableKeyStore extends KeyStore { getPrivateKeys(): Array; getPrivateKey(): any; isValidKey(key: any): Promise; + isEncryptedPrivateKey(privateKey: any): Promise; getFingerprint(): string; getKeyId(key: any): string; getPrivateKeyId(): string; @@ -35,8 +35,6 @@ class MutablePgpKeyStore implements MutableKeyStore{ async loadKeyring(): Promise { await keyring.load(); - // clear any keys already in the keychain - // keyring.clear(); await keyring.store(); } @@ -83,6 +81,17 @@ class MutablePgpKeyStore implements MutableKeyStore{ return !_key.err; } + async isEncryptedPrivateKey(privateKey: any): Promise { + const imported = await openpgp.key.readArmored(privateKey); + for (let i = 0; i < imported.keys.length; i++) { + const key = imported.keys[i]; + if (key.isDecrypted()) { + return false; + } + } + return true; + } + getFingerprint(): string { // TODO Handle multiple keys return keyring.privateKeys.keys[0].keyPacket.fingerprint; diff --git a/src/app/_services/auth.service.ts b/src/app/_services/auth.service.ts index 086127c..30d6d05 100644 --- a/src/app/_services/auth.service.ts +++ b/src/app/_services/auth.service.ts @@ -5,10 +5,8 @@ import {environment} from '@src/environments/environment'; import {LoggingService} from '@app/_services/logging.service'; import {MutableKeyStore, MutablePgpKeyStore} from '@app/_pgp'; import {ErrorDialogService} from '@app/_services/error-dialog.service'; -import {tap} from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; import {Observable } from 'rxjs'; -import * as openpgp from 'openpgp'; @Injectable({ providedIn: 'root' @@ -125,18 +123,19 @@ export class AuthService { } async setKey(privateKeyArmored): Promise { - // TODO Check if key is encrypted else warn user. - try { const isValidKeyCheck = await this.mutableKeyStore.isValidKey(privateKeyArmored); if (!isValidKeyCheck) { throw Error('The private key is invalid'); } + const isEncryptedKeyCheck = await this.mutableKeyStore.isEncryptedPrivateKey(privateKeyArmored); + if (!isEncryptedKeyCheck) { + throw Error('The private key doesn\'t have a password!'); + } const key = await this.mutableKeyStore.importPrivateKey(privateKeyArmored); localStorage.setItem(btoa('CICADA_PRIVATE_KEY'), privateKeyArmored); } catch (err) { - this.loggingService.sendErrorLevelMessage('Failed setting key', this, {error: err}); - // TODO use a global error handler here + this.loggingService.sendErrorLevelMessage(`Failed to set key: ${err.message || err.statusText}`, this, {error: err}); this.errorDialogService.openDialog({ message: `Failed to set key: ${err.message || err.statusText}`, }); @@ -158,14 +157,7 @@ export class AuthService { } getPublicKeys(): Observable { - return this.httpClient.get(`${environment.publicKeysUrl}`, {responseType: 'text'}) - .pipe(tap( - data => { }, - error => { - this.loggingService.sendErrorLevelMessage('Unable to load trusted public keys.', this, {error}); - this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'}); - } - )); + return this.httpClient.get(`${environment.publicKeysUrl}`, {responseType: 'text'}); } async getPrivateKeys(): Promise { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 882bc78..ce9e6f0 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,6 @@ import {ChangeDetectionStrategy, Component, HostListener} from '@angular/core'; -import {AuthService, LoggingService, TokenService, TransactionService} from '@app/_services'; +import {AuthService, ErrorDialogService, LoggingService, TransactionService} from '@app/_services'; +import {catchError} from 'rxjs/operators'; @Component({ selector: 'app-root', @@ -15,15 +16,17 @@ export class AppComponent { constructor( private authService: AuthService, - private tokenService: TokenService, private transactionService: TransactionService, private loggingService: LoggingService, + private errorDialogService: ErrorDialogService ) { (async () => { await this.authService.mutableKeyStore.loadKeyring(); - // TODO Handle error from get public keys function. - this.authService.getPublicKeys().subscribe(this.authService.mutableKeyStore.importPublicKey); - // this.loggingService.sendInfoLevelMessage(await this.tokenService.getTokens()); + this.authService.getPublicKeys() + .pipe(catchError(async (error) => { + this.loggingService.sendErrorLevelMessage('Unable to load trusted public keys.', this, {error}); + this.errorDialogService.openDialog({message: 'Trusted keys endpoint can\'t be reached. Please try again later.'}); + })).subscribe(this.authService.mutableKeyStore.importPublicKey); })(); this.mediaQuery.addListener(this.onResize); this.onResize(this.mediaQuery);