add profile pgp generation

This commit is contained in:
_Bastler 2021-05-30 17:02:07 +02:00
parent 9ab0b9553c
commit 5ee8da9501
7 changed files with 139 additions and 10 deletions

View File

@ -22,6 +22,7 @@ import {TokensComponent} from './pages/tokens/tokens.component';
import {InvitesComponent} from './pages/invites/invites.component'; import {InvitesComponent} from './pages/invites/invites.component';
import {PermissionsComponent} from './ui/permissions/permissions.component'; import {PermissionsComponent} from './ui/permissions/permissions.component';
import {ProfileFieldDialog, ProfileFieldsComponent, ProfileFieldBlob} from './ui/profilefields/profilefields.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 {QuotasComponent} from './ui/quotas/quotas.component';
import {SecurityComponent, SecurityTotpDialog} from './pages/account/security/security.component'; import {SecurityComponent, SecurityTotpDialog} from './pages/account/security/security.component';
import {VoucherComponent} from './pages/account/voucher/voucher.component'; import {VoucherComponent} from './pages/account/voucher/voucher.component';
@ -74,7 +75,7 @@ export class XhrInterceptor implements HttpInterceptor {
InvitesComponent, InvitesComponent,
ServicesComponent, ServicesComponent,
PermissionsComponent, PermissionsComponent,
ProfileFieldsComponent, ProfileFieldDialog, ProfileFieldBlob, ProfileFieldsComponent, ProfileFieldDialog, ProfileFieldBlob, ProfileFieldPgpBlob,
QuotasComponent, QuotasComponent,
SecurityComponent, SecurityComponent,
SecurityTotpDialog, SecurityTotpDialog,

View File

@ -2,7 +2,7 @@ import {Component, OnInit, Inject, ViewChild, ElementRef} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog'; import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {MatSnackBar} from '@angular/material/snack-bar';
import {UserService} from './../../services/user.service'; import {UserService} from './../../services/user.service';
import {ItemService} from './../../services/item.service'; import {ItemService} from './../../services/item.service';
@ -167,6 +167,8 @@ export class RegisterDialog {
@ViewChild("downloadKey", {read: ElementRef}) downloadKey: ElementRef; @ViewChild("downloadKey", {read: ElementRef}) downloadKey: ElementRef;
constructor(private router: Router, constructor(private router: Router,
private i18n : I18nService,
private snackBar: MatSnackBar,
public dialogRef: MatDialogRef<RegisterDialog>, public dialogRef: MatDialogRef<RegisterDialog>,
@Inject(MAT_DIALOG_DATA) public data: any) { @Inject(MAT_DIALOG_DATA) public data: any) {
} }
@ -185,6 +187,9 @@ export class RegisterDialog {
document.execCommand('copy'); document.execCommand('copy');
inputElement.setSelectionRange(0, 0); inputElement.setSelectionRange(0, 0);
this.downloaded = true; this.downloaded = true;
this.snackBar.open(this.i18n.get("pgp.privateKey.copied", []), this.i18n.get("close", []), {
duration: 3000
});
} }
} }

View File

@ -0,0 +1,28 @@
<h1 mat-dialog-title>{{'profileField.blob.pgp' | i18n}}</h1>
<mat-dialog-content>
<h3>{{'pgp.privateKey' | i18n}}</h3>
<mat-form-field>
<qrcode [qrdata]="data.privateKey" [width]="400" [errorCorrectionLevel]="'M'"></qrcode>
<mat-label>{{'pgp.privateKey' | i18n}}</mat-label>
<textarea matInput readonly [(ngModel)]="data.privateKey" #privkey></textarea>
</mat-form-field>
</mat-dialog-content>
<mat-dialog-actions>
<a mat-raised-button color="primary" #downloadKey (click)="setDownloaded()">{{'pgp.privateKey.downloadKey' |
i18n}}</a>
<a mat-raised-button (click)="copyKey(privkey)">{{'pgp.privateKey.copyKey' |
i18n}}</a>
<button mat-icon-button #privateKeyHelp="matTooltip" (click)="privateKeyHelp.toggle()" [matTooltip]="'pgp.privateKey.help' | i18n" matTooltipPosition="after">
<mat-icon>help</mat-icon>
</button>
</mat-dialog-actions>
<br />
<mat-dialog-actions>
<a mat-icon-button (click)="downloaded=true" [matTooltip]="'pgp.privateKey.downloaded' | i18n"><mat-icon>announcement</mat-icon></a>
<mat-slide-toggle [(ngModel)]="data.confirmClose" [disabled]="!downloaded">
{{'pgp.privateKey.confirmStore' | i18n}}
</mat-slide-toggle>
<button mat-button [mat-dialog-close]="false">{{'cancel' | i18n}}</button>
<button mat-button color="accent" [disabled]="!data.confirmClose" [mat-dialog-close]="data.publicKey">{{'ok' | i18n}}</button>
</mat-dialog-actions>

View File

@ -0,0 +1,8 @@
mat-form-field {
display: block;
}
textarea {
width: 100%;
min-height: 200px;
}

View File

@ -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<ProfileFieldPgpBlob>,
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
});
}
}

View File

@ -71,13 +71,16 @@
{{'profileField.error.NUMBER' | i18n}} {{'profileField.error.NUMBER' | i18n}}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field *ngSwitchCase="'BLOB'"> <div *ngSwitchCase="'BLOB'">
<mat-form-field>
<textarea matInput [(ngModel)]="profileField.blob" formControlName="blob" <textarea matInput [(ngModel)]="profileField.blob" formControlName="blob"
placeholder="{{'profileField.value' | i18n}}"></textarea> placeholder="{{'profileField.value' | i18n}}"></textarea>
<mat-error> <mat-error>
{{'profileField.error.BLOB' | i18n}} {{'profileField.error.BLOB' | i18n}}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
<a mat-button (click)="pgpBlob(profileField)">{{'profileField.blob.pgp' | i18n}}</a>
</div>
</div> </div>

View File

@ -5,6 +5,7 @@ import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog
import {ConfirmDialog} from '../confirm/confirm.component'; import {ConfirmDialog} from '../confirm/confirm.component';
import {I18nService} from '../../services/i18n.service'; import {I18nService} from '../../services/i18n.service';
import {ProfileService} from '../../services/profile.service'; import {ProfileService} from '../../services/profile.service';
import {ProfileFieldPgpBlob} from './binary/pgp/profilefield.pgp-blob';
@Component({ @Component({
selector: 'app-profilefields', selector: 'app-profilefields',
@ -154,6 +155,7 @@ export class ProfileFieldDialog {
constructor( constructor(
private profileService: ProfileService, private profileService: ProfileService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private dialog: MatDialog,
public dialogRef: MatDialogRef<ProfileFieldDialog>, public dialogRef: MatDialogRef<ProfileFieldDialog>,
@Inject(MAT_DIALOG_DATA) public data: any) { @Inject(MAT_DIALOG_DATA) public data: any) {
this.profileField = data; 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;
}
});
}
} }