From 5ee8da950159002420f7a2d9604fc3cb9f452582 Mon Sep 17 00:00:00 2001 From: _Bastler <_Bastler@bstly.de> Date: Sun, 30 May 2021 17:02:07 +0200 Subject: [PATCH] add profile pgp generation --- src/app/app.module.ts | 3 +- src/app/pages/register/register.component.ts | 7 +- .../binary/pgp/profilefield.pgp-blob.html | 28 ++++++++ .../binary/pgp/profilefield.pgp-blob.scss | 8 +++ .../binary/pgp/profilefield.pgp-blob.ts | 68 +++++++++++++++++++ .../ui/profilefields/profilefield.dialog.html | 17 +++-- .../profilefields/profilefields.component.ts | 18 ++++- 7 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.html create mode 100644 src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.scss create mode 100644 src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ef7ec05..a2f1a0b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -22,6 +22,7 @@ import {TokensComponent} from './pages/tokens/tokens.component'; import {InvitesComponent} from './pages/invites/invites.component'; import {PermissionsComponent} from './ui/permissions/permissions.component'; import {ProfileFieldDialog, ProfileFieldsComponent, ProfileFieldBlob} from './ui/profilefields/profilefields.component'; +import {ProfileFieldPgpBlob} from './ui/profilefields/binary/pgp/profilefield.pgp-blob'; import {QuotasComponent} from './ui/quotas/quotas.component'; import {SecurityComponent, SecurityTotpDialog} from './pages/account/security/security.component'; import {VoucherComponent} from './pages/account/voucher/voucher.component'; @@ -74,7 +75,7 @@ export class XhrInterceptor implements HttpInterceptor { InvitesComponent, ServicesComponent, PermissionsComponent, - ProfileFieldsComponent, ProfileFieldDialog, ProfileFieldBlob, + ProfileFieldsComponent, ProfileFieldDialog, ProfileFieldBlob, ProfileFieldPgpBlob, QuotasComponent, SecurityComponent, SecurityTotpDialog, diff --git a/src/app/pages/register/register.component.ts b/src/app/pages/register/register.component.ts index 3f35605..a778eda 100644 --- a/src/app/pages/register/register.component.ts +++ b/src/app/pages/register/register.component.ts @@ -2,7 +2,7 @@ import {Component, OnInit, Inject, ViewChild, ElementRef} from '@angular/core'; import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; import {Router} from '@angular/router'; - +import {MatSnackBar} from '@angular/material/snack-bar'; import {UserService} from './../../services/user.service'; import {ItemService} from './../../services/item.service'; @@ -167,6 +167,8 @@ export class RegisterDialog { @ViewChild("downloadKey", {read: ElementRef}) downloadKey: ElementRef; constructor(private router: Router, + private i18n : I18nService, + private snackBar: MatSnackBar, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any) { } @@ -185,6 +187,9 @@ export class RegisterDialog { document.execCommand('copy'); inputElement.setSelectionRange(0, 0); this.downloaded = true; + this.snackBar.open(this.i18n.get("pgp.privateKey.copied", []), this.i18n.get("close", []), { + duration: 3000 + }); } } diff --git a/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.html b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.html new file mode 100644 index 0000000..ab86361 --- /dev/null +++ b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.html @@ -0,0 +1,28 @@ +

{{'profileField.blob.pgp' | i18n}}

+ +

{{'pgp.privateKey' | i18n}}

+ + + + {{'pgp.privateKey' | i18n}} + + +
+ + {{'pgp.privateKey.downloadKey' | + i18n}} + {{'pgp.privateKey.copyKey' | + i18n}} + + +
+ + announcement + + {{'pgp.privateKey.confirmStore' | i18n}} + + + + \ No newline at end of file diff --git a/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.scss b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.scss new file mode 100644 index 0000000..f222da9 --- /dev/null +++ b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.scss @@ -0,0 +1,8 @@ +mat-form-field { + display: block; +} + +textarea { + width: 100%; + min-height: 200px; +} \ No newline at end of file diff --git a/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.ts b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.ts new file mode 100644 index 0000000..720ac78 --- /dev/null +++ b/src/app/ui/profilefields/binary/pgp/profilefield.pgp-blob.ts @@ -0,0 +1,68 @@ +import {Component, OnInit, ElementRef, ViewChild} from '@angular/core'; +import {MatDialogRef} from '@angular/material/dialog'; +import {MatSnackBar} from '@angular/material/snack-bar'; + +import {AuthService} from '../../../../services/auth.service'; +import {I18nService} from '../../../../services/i18n.service'; + + + +var openpgp = require('openpgp'); + +@Component({ + templateUrl: './profilefield.pgp-blob.html', + styleUrls: ['./profilefield.pgp-blob.scss'] +}) +export class ProfileFieldPgpBlob implements OnInit { + + public downloaded: boolean = false; + + data: any; + + @ViewChild("downloadKey", {read: ElementRef}) downloadKey: ElementRef; + constructor( + public dialogRef: MatDialogRef, + private i18n : I18nService, + private authService: AuthService, + private snackBar: MatSnackBar) { + this.data = {}; + } + + ngOnInit(): void { + this.authService.getAuth().then((auth: any) => { + if(!auth.authenticated) { + return; + } + + let pgpOption = { + userIds: [{name: auth.principal.username, email: auth.principal.username + "@we.bstly.de"}], + curve: "ed25519", + } + + openpgp.generateKey(pgpOption).then((key) => { + this.data = {}; + this.data.privateKey = key.privateKeyArmored; + this.data.publicKey = key.publicKeyArmored; + + this.downloadKey.nativeElement.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(this.data.privateKey)); + this.downloadKey.nativeElement.setAttribute('download', auth.principal.username + ".private.key"); + }); + + }); + } + + setDownloaded() { + this.downloaded = true; + } + + copyKey(inputElement) { + inputElement.select(); + document.execCommand('copy'); + inputElement.setSelectionRange(0, 0); + this.downloaded = true; + this.snackBar.open(this.i18n.get("pgp.privateKey.copied", []), this.i18n.get("close", []), { + duration: 3000 + }); + } + +} \ No newline at end of file diff --git a/src/app/ui/profilefields/profilefield.dialog.html b/src/app/ui/profilefields/profilefield.dialog.html index 7a150e4..4608af3 100644 --- a/src/app/ui/profilefields/profilefield.dialog.html +++ b/src/app/ui/profilefields/profilefield.dialog.html @@ -71,13 +71,16 @@ {{'profileField.error.NUMBER' | i18n}} - - - - {{'profileField.error.BLOB' | i18n}} - - +
+ + + + {{'profileField.error.BLOB' | i18n}} + + + {{'profileField.blob.pgp' | i18n}} +
diff --git a/src/app/ui/profilefields/profilefields.component.ts b/src/app/ui/profilefields/profilefields.component.ts index 193082e..d38d45e 100644 --- a/src/app/ui/profilefields/profilefields.component.ts +++ b/src/app/ui/profilefields/profilefields.component.ts @@ -5,6 +5,7 @@ import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog import {ConfirmDialog} from '../confirm/confirm.component'; import {I18nService} from '../../services/i18n.service'; import {ProfileService} from '../../services/profile.service'; +import {ProfileFieldPgpBlob} from './binary/pgp/profilefield.pgp-blob'; @Component({ selector: 'app-profilefields', @@ -153,7 +154,8 @@ export class ProfileFieldDialog { constructor( private profileService: ProfileService, - private formBuilder: FormBuilder, + private formBuilder: FormBuilder, + private dialog: MatDialog, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any) { this.profileField = data; @@ -197,6 +199,20 @@ export class ProfileFieldDialog { }); } + pgpBlob(profileField) { + const dialogRef = this.dialog.open(ProfileFieldPgpBlob, { + minWidth: '400px' + }); + + dialogRef.afterClosed().subscribe(result => { + if(result) { + console.log(result, profileField); + profileField.blob = result; + } + }); + + } + }