fix(console): show otp secret (#4030)

This commit is contained in:
Max Peintner 2022-07-22 15:44:16 +02:00 committed by GitHub
parent 9fc8a43642
commit 955e4d483e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 26 deletions

View File

@ -1,33 +1,53 @@
<h1 mat-dialog-title>
<span class="title">{{'APP.OIDC.CLIENTSECRET' | translate}}</span>
<span class="title">{{ 'APP.OIDC.CLIENTSECRET' | translate }}</span>
</h1>
<p class="desc cnsl-secondary-text">{{'APP.OIDC.CLIENTSECRET_DESCRIPTION' | translate}}</p>
<p class="desc cnsl-secondary-text">{{ 'APP.OIDC.CLIENTSECRET_DESCRIPTION' | translate }}</p>
<div mat-dialog-content>
<div class="flex" *ngIf="data.clientId">
<span class="overflow-auto"><span class="desc">ClientId:</span> {{data.clientId}}</span>
<button color="primary" [disabled]="copied === data.clientId" matTooltip="copy to clipboard" cnslCopyToClipboard
[valueToCopy]="data.clientId" (copiedValue)="this.copied = $event" mat-icon-button>
<span class="overflow-auto"><span class="desc">ClientId:</span> {{ data.clientId }}</span>
<button
color="primary"
[disabled]="copied === data.clientId"
matTooltip="copy to clipboard"
cnslCopyToClipboard
[valueToCopy]="data.clientId"
(copiedValue)="this.copied = $event"
mat-icon-button
>
<i *ngIf="copied !== data.clientId" class="las la-clipboard"></i>
<i *ngIf="copied === data.clientId" class="las la-clipboard-check"></i>
</button>
</div>
<div *ngIf="data.clientSecret; else showNoSecretInfo" class="flex">
<span class="overflow-auto"><span class="desc cnsl-secondary-text">ClientSecret:</span> {{data.clientSecret}}</span>
<button color="primary" [disabled]="copied === data.clientSecret" matTooltip="copy to clipboard" cnslCopyToClipboard
[valueToCopy]="data.clientSecret" (copiedValue)="this.copied = $event" mat-icon-button>
<span class="overflow-auto"><span class="desc cnsl-secondary-text">ClientSecret:</span> {{ data.clientSecret }}</span>
<button
color="primary"
[disabled]="copied === data.clientSecret"
matTooltip="copy to clipboard"
cnslCopyToClipboard
[valueToCopy]="data.clientSecret"
(copiedValue)="this.copied = $event"
mat-icon-button
>
<i *ngIf="copied !== data.clientSecret" class="las la-clipboard"></i>
<i *ngIf="copied === data.clientSecret" class="las la-clipboard-check"></i>
</button>
</div>
<ng-template #showNoSecretInfo>
<cnsl-info-section>{{'APP.OIDC.CLIENTSECRET_NOSECRET' | translate}}</cnsl-info-section>
<cnsl-info-section>{{ 'APP.OIDC.CLIENTSECRET_NOSECRET' | translate }}</cnsl-info-section>
</ng-template>
</div>
<div mat-dialog-actions class="action">
<button cdkFocusInitial color="primary" mat-raised-button class="ok-button" (click)="closeDialog()"
[attr.data-e2e]="'close-dialog'">
{{'ACTIONS.CLOSE' | translate}}
<button
cdkFocusInitial
color="primary"
mat-raised-button
class="ok-button"
(click)="closeDialog()"
[attr.data-e2e]="'close-dialog'"
>
{{ 'ACTIONS.CLOSE' | translate }}
</button>
</div>
</div>

View File

@ -1,15 +1,15 @@
<h1 mat-dialog-title>
<span class="title">{{'USER.MFA.DIALOG.ADD_MFA_TITLE' | translate}} {{data?.number}}</span>
<span class="title">{{ 'USER.MFA.DIALOG.ADD_MFA_TITLE' | translate }} {{ data?.number }}</span>
</h1>
<div mat-dialog-content>
<ng-container *ngIf="selectedType === undefined">
<p class="desc cnsl-secondary-text">{{'USER.MFA.DIALOG.ADD_MFA_DESCRIPTION' | translate}}</p>
<p class="desc cnsl-secondary-text">{{ 'USER.MFA.DIALOG.ADD_MFA_DESCRIPTION' | translate }}</p>
<div class="type-selection">
<button mat-raised-button color="primary" [disabled]="data.otpDisabled" (click)="selectType(AuthFactorType.OTP)">
<div class="otp-btn">
<mat-icon class="icon" svgIcon="mdi_radar"></mat-icon>
<span>{{'USER.MFA.OTP' | translate}}</span>
<span>{{ 'USER.MFA.OTP' | translate }}</span>
</div>
</button>
<button mat-raised-button color="primary" (click)="selectType(AuthFactorType.U2F)">
@ -19,17 +19,33 @@
<i matTooltip="Security Key" class="lab la-usb"></i>
<mat-icon matTooltip="NFC">nfc</mat-icon>
</div>
<span>{{'USER.MFA.U2F' | translate}}</span>
<span>{{ 'USER.MFA.U2F' | translate }}</span>
</div>
</button>
</div>
</ng-container>
<div class="otp" *ngIf="selectedType === AuthFactorType.OTP">
<p class="desc cnsl-secondary-text">{{'USER.MFA.OTP_DIALOG_DESCRIPTION' | translate}}</p>
<p class="desc cnsl-secondary-text">{{ 'USER.MFA.OTP_DIALOG_DESCRIPTION' | translate }}</p>
<div class="qrcode-wrapper">
<qr-code *ngIf="otpurl" class="qrcode" [value]="otpurl" [size]="150" [errorCorrectionLevel]="'M'"></qr-code>
<div class="otp-flex" *ngIf="otpsecret">
<span class="overflow-auto">{{ otpsecret }}</span>
<button
color="primary"
[disabled]="copied === otpsecret"
matTooltip="copy to clipboard"
cnslCopyToClipboard
[valueToCopy]="otpsecret"
(copiedValue)="this.copied = $event"
mat-icon-button
>
<i *ngIf="copied !== otpsecret" class="las la-clipboard"></i>
<i *ngIf="copied === otpsecret" class="las la-clipboard-check"></i>
</button>
</div>
</div>
<cnsl-form-field class="formfield" label="Access Code" required="true">
@ -39,25 +55,31 @@
</div>
<div class="u2f" *ngIf="selectedType === AuthFactorType.U2F">
<p>{{'USER.MFA.U2F_DIALOG_DESCRIPTION' | translate}}</p>
<p>{{ 'USER.MFA.U2F_DIALOG_DESCRIPTION' | translate }}</p>
<cnsl-form-field class="form-field" label="Name" required="true">
<cnsl-label>{{'USER.MFA.U2F_NAME' | translate}}</cnsl-label>
<cnsl-label>{{ 'USER.MFA.U2F_NAME' | translate }}</cnsl-label>
<input cnslInput [(ngModel)]="u2fname" required (keydown.enter)="u2fname ? submitU2F() : null" />
</cnsl-form-field>
<mat-spinner diameter="30" *ngIf="u2fLoading"></mat-spinner>
<p class="error">{{u2fError}}</p>
<p class="error">{{ u2fError }}</p>
</div>
</div>
<div mat-dialog-actions class="action">
<button mat-stroked-button class="ok-button" (click)="closeDialog()">
{{'ACTIONS.CLOSE' | translate}}
{{ 'ACTIONS.CLOSE' | translate }}
</button>
<button *ngIf="selectedType !== undefined" cdkFocusInitial color="primary" mat-raised-button class="ok-button"
(click)="submitAuth()">
{{'ACTIONS.CREATE' | translate}}
<button
*ngIf="selectedType !== undefined"
cdkFocusInitial
color="primary"
mat-raised-button
class="ok-button"
(click)="submitAuth()"
>
{{ 'ACTIONS.CREATE' | translate }}
</button>
</div>
</div>

View File

@ -33,6 +33,29 @@
display: flex;
flex-direction: column;
align-items: center;
.qrcode-wrapper {
display: flex;
flex-direction: column;
align-items: center;
.otp-flex {
display: flex;
align-items: center;
border: 1px solid #ffffff20;
border-radius: 0.5rem;
padding-left: 0.5rem;
justify-content: space-between;
.overflow-auto {
overflow: auto;
.desc {
font-size: 14px;
}
}
}
}
}
.u2f {

View File

@ -20,6 +20,8 @@ export enum AuthFactorType {
})
export class AuthFactorDialogComponent {
public otpurl: string = '';
public otpsecret: string = '';
public otpcode: string = '';
public u2fname: string = '';
@ -29,6 +31,8 @@ export class AuthFactorDialogComponent {
AuthFactorType: any = AuthFactorType;
selectedType!: AuthFactorType;
public copied: string = '';
constructor(
private authService: GrpcAuthService,
private toast: ToastService,
@ -48,6 +52,7 @@ export class AuthFactorDialogComponent {
this.authService.addMyMultiFactorOTP().then(
(otpresp) => {
this.otpurl = otpresp.url;
this.otpsecret = otpresp.secret;
},
(error) => {
this.toast.showError(error);