mirror of
https://github.com/bitwarden/desktop.git
synced 2024-11-28 12:35:40 +01:00
parent
20b8a83dd8
commit
42564285d9
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit e298ecfee378e6620e8e086362d9af744c5af8ff
|
Subproject commit a72c8a60c1b7a6980bceee456c53a9ea7b9b3451
|
@ -7,14 +7,13 @@ import {
|
|||||||
import { ToasterModule } from 'angular2-toaster';
|
import { ToasterModule } from 'angular2-toaster';
|
||||||
|
|
||||||
import { ElectronLogService } from 'jslib/electron/services/electronLog.service';
|
import { ElectronLogService } from 'jslib/electron/services/electronLog.service';
|
||||||
import { ElectronPlatformUtilsService } from 'jslib/electron/services/electronPlatformUtils.service';
|
|
||||||
import { ElectronRendererMessagingService } from 'jslib/electron/services/electronRendererMessaging.service';
|
import { ElectronRendererMessagingService } from 'jslib/electron/services/electronRendererMessaging.service';
|
||||||
import { ElectronRendererSecureStorageService } from 'jslib/electron/services/electronRendererSecureStorage.service';
|
import { ElectronRendererSecureStorageService } from 'jslib/electron/services/electronRendererSecureStorage.service';
|
||||||
import { ElectronRendererStorageService } from 'jslib/electron/services/electronRendererStorage.service';
|
import { ElectronRendererStorageService } from 'jslib/electron/services/electronRendererStorage.service';
|
||||||
import { isDev } from 'jslib/electron/utils';
|
|
||||||
|
|
||||||
import { DeviceType } from 'jslib/enums/deviceType';
|
import { DeviceType } from 'jslib/enums/deviceType';
|
||||||
|
|
||||||
|
import { ElectronPlatformUtilsService } from '../services/electronPlatformUtils.service';
|
||||||
import { I18nService } from '../services/i18n.service';
|
import { I18nService } from '../services/i18n.service';
|
||||||
import { NativeMessagingService } from '../services/nativeMessaging.service';
|
import { NativeMessagingService } from '../services/nativeMessaging.service';
|
||||||
|
|
||||||
@ -54,7 +53,6 @@ import { VaultTimeoutService } from 'jslib/services/vaultTimeout.service';
|
|||||||
import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service';
|
import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service';
|
||||||
|
|
||||||
import { ApiService as ApiServiceAbstraction } from 'jslib/abstractions/api.service';
|
import { ApiService as ApiServiceAbstraction } from 'jslib/abstractions/api.service';
|
||||||
import { AppIdService as AppIdServiceAbstraction } from 'jslib/abstractions/appId.service';
|
|
||||||
import { AuditService as AuditServiceAbstraction } from 'jslib/abstractions/audit.service';
|
import { AuditService as AuditServiceAbstraction } from 'jslib/abstractions/audit.service';
|
||||||
import { AuthService as AuthServiceAbstraction } from 'jslib/abstractions/auth.service';
|
import { AuthService as AuthServiceAbstraction } from 'jslib/abstractions/auth.service';
|
||||||
import { CipherService as CipherServiceAbstraction } from 'jslib/abstractions/cipher.service';
|
import { CipherService as CipherServiceAbstraction } from 'jslib/abstractions/cipher.service';
|
||||||
@ -73,6 +71,7 @@ import { NotificationsService as NotificationsServiceAbstraction } from 'jslib/a
|
|||||||
import {
|
import {
|
||||||
PasswordGenerationService as PasswordGenerationServiceAbstraction,
|
PasswordGenerationService as PasswordGenerationServiceAbstraction,
|
||||||
} from 'jslib/abstractions/passwordGeneration.service';
|
} from 'jslib/abstractions/passwordGeneration.service';
|
||||||
|
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from 'jslib/abstractions/passwordReprompt.service';
|
||||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib/abstractions/platformUtils.service';
|
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from 'jslib/abstractions/platformUtils.service';
|
||||||
import { PolicyService as PolicyServiceAbstraction } from 'jslib/abstractions/policy.service';
|
import { PolicyService as PolicyServiceAbstraction } from 'jslib/abstractions/policy.service';
|
||||||
import { SearchService as SearchServiceAbstraction } from 'jslib/abstractions/search.service';
|
import { SearchService as SearchServiceAbstraction } from 'jslib/abstractions/search.service';
|
||||||
@ -86,6 +85,7 @@ import { TokenService as TokenServiceAbstraction } from 'jslib/abstractions/toke
|
|||||||
import { TotpService as TotpServiceAbstraction } from 'jslib/abstractions/totp.service';
|
import { TotpService as TotpServiceAbstraction } from 'jslib/abstractions/totp.service';
|
||||||
import { UserService as UserServiceAbstraction } from 'jslib/abstractions/user.service';
|
import { UserService as UserServiceAbstraction } from 'jslib/abstractions/user.service';
|
||||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib/abstractions/vaultTimeout.service';
|
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from 'jslib/abstractions/vaultTimeout.service';
|
||||||
|
import { PasswordRepromptService } from 'jslib/services/passwordReprompt.service';
|
||||||
|
|
||||||
const logService = new ElectronLogService();
|
const logService = new ElectronLogService();
|
||||||
const i18nService = new I18nService(window.navigator.language, './locales');
|
const i18nService = new I18nService(window.navigator.language, './locales');
|
||||||
@ -137,6 +137,7 @@ const systemService = new SystemService(storageService, vaultTimeoutService, mes
|
|||||||
null);
|
null);
|
||||||
const nativeMessagingService = new NativeMessagingService(cryptoFunctionService, cryptoService, platformUtilsService,
|
const nativeMessagingService = new NativeMessagingService(cryptoFunctionService, cryptoService, platformUtilsService,
|
||||||
logService, i18nService, userService, messagingService, vaultTimeoutService, storageService);
|
logService, i18nService, userService, messagingService, vaultTimeoutService, storageService);
|
||||||
|
const passwordRepromptService = new PasswordRepromptService(i18nService, cryptoService, platformUtilsService);
|
||||||
|
|
||||||
containerService.attachToGlobal(window);
|
containerService.attachToGlobal(window);
|
||||||
|
|
||||||
@ -223,6 +224,7 @@ export function initFactory(): Function {
|
|||||||
{ provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService },
|
{ provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService },
|
||||||
{ provide: NativeMessagingService, useValue: nativeMessagingService },
|
{ provide: NativeMessagingService, useValue: nativeMessagingService },
|
||||||
{ provide: FileUploadServiceAbstraction, useValue: fileUploadService },
|
{ provide: FileUploadServiceAbstraction, useValue: fileUploadService },
|
||||||
|
{ provide: PasswordRepromptServiceAbstraction, useValue: passwordRepromptService },
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: initFactory,
|
useFactory: initFactory,
|
||||||
|
@ -66,9 +66,19 @@
|
|||||||
<input id="cardCardholderName" type="text" name="Card.CardCardholderName"
|
<input id="cardCardholderName" type="text" name="Card.CardCardholderName"
|
||||||
[(ngModel)]="cipher.card.cardholderName">
|
[(ngModel)]="cipher.card.cardholderName">
|
||||||
</div>
|
</div>
|
||||||
<div class="box-content-row" appBoxRow>
|
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||||
<label for="cardNumber">{{'number' | i18n}}</label>
|
<div class="row-main">
|
||||||
<input id="cardNumber" type="text" name="Card.Number" [(ngModel)]="cipher.card.number">
|
<label for="cardNumber">{{'number' | i18n}}</label>
|
||||||
|
<input id="cardNumber" class="monospaced" type="{{showCardNumber ? 'text' : 'password'}}"
|
||||||
|
name="Card.Number" [(ngModel)]="cipher.card.number">
|
||||||
|
</div>
|
||||||
|
<div class="action-buttons">
|
||||||
|
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
|
||||||
|
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="toggleCardNumber()">
|
||||||
|
<i class="fa fa-lg" aria-hidden="true"
|
||||||
|
[ngClass]="{'fa-eye': !showCardNumber, 'fa-eye-slash': showCardNumber}"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-content-row" appBoxRow>
|
<div class="box-content-row" appBoxRow>
|
||||||
<label for="cardBrand">{{'brand' | i18n}}</label>
|
<label for="cardBrand">{{'brand' | i18n}}</label>
|
||||||
@ -239,6 +249,11 @@
|
|||||||
<label for="favorite">{{'favorite' | i18n}}</label>
|
<label for="favorite">{{'favorite' | i18n}}</label>
|
||||||
<input id="favorite" type="checkbox" name="Favorite" [(ngModel)]="cipher.favorite">
|
<input id="favorite" type="checkbox" name="Favorite" [(ngModel)]="cipher.favorite">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||||
|
<label for="passwordPrompt">{{'passwordPrompt' | i18n}}</label>
|
||||||
|
<input id="passwordPrompt" type="checkbox" name="PasswordPrompt" [ngModel]="reprompt"
|
||||||
|
(change)="repromptChanged()">
|
||||||
|
</div>
|
||||||
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
|
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
|
||||||
(click)="attachments()" *ngIf="editMode && !cloneMode" role="button">
|
(click)="attachments()" *ngIf="editMode && !cloneMode" role="button">
|
||||||
<div class="row-main">{{'attachments' | i18n}}</div>
|
<div class="row-main">{{'attachments' | i18n}}</div>
|
||||||
|
@ -39,11 +39,13 @@ import { FolderView } from 'jslib/models/view/folderView';
|
|||||||
import { EventService } from 'jslib/abstractions/event.service';
|
import { EventService } from 'jslib/abstractions/event.service';
|
||||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
|
import { PasswordRepromptService } from 'jslib/abstractions/passwordReprompt.service';
|
||||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||||
import { SyncService } from 'jslib/abstractions/sync.service';
|
import { SyncService } from 'jslib/abstractions/sync.service';
|
||||||
import { TotpService } from 'jslib/abstractions/totp.service';
|
import { TotpService } from 'jslib/abstractions/totp.service';
|
||||||
import { UserService } from 'jslib/abstractions/user.service';
|
import { UserService } from 'jslib/abstractions/user.service';
|
||||||
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
|
import { invokeMenu, RendererMenuItem } from 'jslib/electron/utils';
|
||||||
|
import { CipherRepromptType } from 'jslib/enums/cipherRepromptType';
|
||||||
|
|
||||||
const BroadcasterSubscriptionId = 'VaultComponent';
|
const BroadcasterSubscriptionId = 'VaultComponent';
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
private ngZone: NgZone, private syncService: SyncService,
|
private ngZone: NgZone, private syncService: SyncService,
|
||||||
private toasterService: ToasterService, private messagingService: MessagingService,
|
private toasterService: ToasterService, private messagingService: MessagingService,
|
||||||
private platformUtilsService: PlatformUtilsService, private eventService: EventService,
|
private platformUtilsService: PlatformUtilsService, private eventService: EventService,
|
||||||
private totpService: TotpService, private userService: UserService) { }
|
private totpService: TotpService, private userService: UserService, private passwordRepromptService: PasswordRepromptService) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
this.userHasPremiumAccess = await this.userService.canAccessPremium();
|
||||||
@ -129,7 +131,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
const uCipher = uComponent != null ? uComponent.cipher : null;
|
const uCipher = uComponent != null ? uComponent.cipher : null;
|
||||||
if (this.cipherId != null && uCipher != null && uCipher.id === this.cipherId &&
|
if (this.cipherId != null && uCipher != null && uCipher.id === this.cipherId &&
|
||||||
uCipher.login != null && uCipher.login.username != null) {
|
uCipher.login != null && uCipher.login.username != null) {
|
||||||
this.copyValue(uCipher.login.username, 'username');
|
this.copyValue(uCipher, uCipher.login.username, 'username', 'Username');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'copyPassword':
|
case 'copyPassword':
|
||||||
@ -137,7 +139,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
const pCipher = pComponent != null ? pComponent.cipher : null;
|
const pCipher = pComponent != null ? pComponent.cipher : null;
|
||||||
if (this.cipherId != null && pCipher != null && pCipher.id === this.cipherId &&
|
if (this.cipherId != null && pCipher != null && pCipher.id === this.cipherId &&
|
||||||
pCipher.login != null && pCipher.login.password != null && pCipher.viewPassword) {
|
pCipher.login != null && pCipher.login.password != null && pCipher.viewPassword) {
|
||||||
this.copyValue(pCipher.login.password, 'password');
|
this.copyValue(pCipher, pCipher.login.password, 'password', 'Password');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'copyTotp':
|
case 'copyTotp':
|
||||||
@ -146,7 +148,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
if (this.cipherId != null && tCipher != null && tCipher.id === this.cipherId &&
|
if (this.cipherId != null && tCipher != null && tCipher.id === this.cipherId &&
|
||||||
tCipher.login != null && tCipher.login.hasTotp && this.userHasPremiumAccess) {
|
tCipher.login != null && tCipher.login.hasTotp && this.userHasPremiumAccess) {
|
||||||
const value = await this.totpService.getCode(tCipher.login.totp);
|
const value = await this.totpService.getCode(tCipher.login.totp);
|
||||||
this.copyValue(value, 'verificationCodeTotp');
|
this.copyValue(tCipher, value, 'verificationCodeTotp', 'TOTP');
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
detectChanges = false;
|
detectChanges = false;
|
||||||
@ -276,14 +278,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
if (cipher.login.username != null) {
|
if (cipher.login.username != null) {
|
||||||
menu.push({
|
menu.push({
|
||||||
label: this.i18nService.t('copyUsername'),
|
label: this.i18nService.t('copyUsername'),
|
||||||
click: () => this.copyValue(cipher.login.username, 'username'),
|
click: () => this.copyValue(cipher, cipher.login.username, 'username', 'Username'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (cipher.login.password != null && cipher.viewPassword) {
|
if (cipher.login.password != null && cipher.viewPassword) {
|
||||||
menu.push({
|
menu.push({
|
||||||
label: this.i18nService.t('copyPassword'),
|
label: this.i18nService.t('copyPassword'),
|
||||||
click: () => {
|
click: () => {
|
||||||
this.copyValue(cipher.login.password, 'password');
|
this.copyValue(cipher, cipher.login.password, 'password', 'Password');
|
||||||
this.eventService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id);
|
this.eventService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -293,7 +295,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
label: this.i18nService.t('copyVerificationCodeTotp'),
|
label: this.i18nService.t('copyVerificationCodeTotp'),
|
||||||
click: async () => {
|
click: async () => {
|
||||||
const value = await this.totpService.getCode(cipher.login.totp);
|
const value = await this.totpService.getCode(cipher.login.totp);
|
||||||
this.copyValue(value, 'verificationCodeTotp');
|
this.copyValue(cipher, value, 'verificationCodeTotp', 'TOTP');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -305,14 +307,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
if (cipher.card.number != null) {
|
if (cipher.card.number != null) {
|
||||||
menu.push({
|
menu.push({
|
||||||
label: this.i18nService.t('copyNumber'),
|
label: this.i18nService.t('copyNumber'),
|
||||||
click: () => this.copyValue(cipher.card.number, 'number'),
|
click: () => this.copyValue(cipher, cipher.card.number, 'number', 'Card Number'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (cipher.card.code != null) {
|
if (cipher.card.code != null) {
|
||||||
menu.push({
|
menu.push({
|
||||||
label: this.i18nService.t('copySecurityCode'),
|
label: this.i18nService.t('copySecurityCode'),
|
||||||
click: () => {
|
click: () => {
|
||||||
this.copyValue(cipher.card.code, 'securityCode');
|
this.copyValue(cipher, cipher.card.code, 'securityCode', 'Security Code');
|
||||||
this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
|
this.eventService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -330,6 +332,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
} else if (this.dirtyInput() && await this.wantsToSaveChanges()) {
|
} else if (this.dirtyInput() && await this.wantsToSaveChanges()) {
|
||||||
return;
|
return;
|
||||||
|
} else if (cipher.reprompt !== CipherRepromptType.None && !await this.passwordRepromptService.showPasswordPrompt()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cipherId = cipher.id;
|
this.cipherId = cipher.id;
|
||||||
@ -342,6 +346,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
return;
|
return;
|
||||||
} else if (this.dirtyInput() && await this.wantsToSaveChanges()) {
|
} else if (this.dirtyInput() && await this.wantsToSaveChanges()) {
|
||||||
return;
|
return;
|
||||||
|
} else if (cipher.reprompt !== CipherRepromptType.None && !await this.passwordRepromptService.showPasswordPrompt()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cipherId = cipher.id;
|
this.cipherId = cipher.id;
|
||||||
@ -639,8 +645,13 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.functionWithChangeDetection(() => this.addCipher(type));
|
this.functionWithChangeDetection(() => this.addCipher(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private copyValue(value: string, labelI18nKey: string) {
|
private copyValue(cipher: CipherView, value: string, labelI18nKey: string, aType: string) {
|
||||||
this.functionWithChangeDetection(() => {
|
this.functionWithChangeDetection(async () => {
|
||||||
|
if (cipher.reprompt !== CipherRepromptType.None && this.passwordRepromptService.protectedFields().includes(aType) &&
|
||||||
|
!await this.passwordRepromptService.showPasswordPrompt()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.platformUtilsService.copyToClipboard(value);
|
this.platformUtilsService.copyToClipboard(value);
|
||||||
this.toasterService.popAsync('info', null,
|
this.toasterService.popAsync('info', null,
|
||||||
this.i18nService.t('valueCopied', this.i18nService.t(labelI18nKey)));
|
this.i18nService.t('valueCopied', this.i18nService.t(labelI18nKey)));
|
||||||
|
@ -87,11 +87,17 @@
|
|||||||
<div class="box-content-row box-content-row-flex" *ngIf="cipher.card.number">
|
<div class="box-content-row box-content-row-flex" *ngIf="cipher.card.number">
|
||||||
<div class="row-main">
|
<div class="row-main">
|
||||||
<span class="row-label">{{'number' | i18n}}</span>
|
<span class="row-label">{{'number' | i18n}}</span>
|
||||||
{{cipher.card.number}}
|
<span [hidden]="showCardNumber" class="monospaced">{{cipher.card.maskedNumber}}</span>
|
||||||
|
<span [hidden]="!showCardNumber" class="monospaced">{{cipher.card.number}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
|
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'toggleVisibility' | i18n}}"
|
||||||
|
(click)="toggleCardNumber()" role="button">
|
||||||
|
<i class="fa fa-lg" aria-hidden="true"
|
||||||
|
[ngClass]="{'fa-eye': !showCardNumber, 'fa-eye-slash': showCardNumber}"></i>
|
||||||
|
</a>
|
||||||
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'copyNumber' | i18n}}"
|
<a class="row-btn" href="#" appStopClick appA11yTitle="{{'copyNumber' | i18n}}"
|
||||||
(click)="copy(cipher.card.number, 'number', 'Number')" role="button">
|
(click)="copy(cipher.card.number, 'number', 'Card Number')" role="button">
|
||||||
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +14,7 @@ import { CryptoService } from 'jslib/abstractions/crypto.service';
|
|||||||
import { EventService } from 'jslib/abstractions/event.service';
|
import { EventService } from 'jslib/abstractions/event.service';
|
||||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
|
import { PasswordRepromptService } from 'jslib/abstractions/passwordReprompt.service';
|
||||||
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
|
||||||
import { StorageService } from 'jslib/abstractions/storage.service';
|
import { StorageService } from 'jslib/abstractions/storage.service';
|
||||||
import { TokenService } from 'jslib/abstractions/token.service';
|
import { TokenService } from 'jslib/abstractions/token.service';
|
||||||
@ -41,9 +42,10 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
|
|||||||
auditService: AuditService, broadcasterService: BroadcasterService,
|
auditService: AuditService, broadcasterService: BroadcasterService,
|
||||||
ngZone: NgZone, changeDetectorRef: ChangeDetectorRef,
|
ngZone: NgZone, changeDetectorRef: ChangeDetectorRef,
|
||||||
userService: UserService, eventService: EventService, apiService: ApiService,
|
userService: UserService, eventService: EventService, apiService: ApiService,
|
||||||
private messagingService: MessagingService, private storageService: StorageService) {
|
private messagingService: MessagingService, passwordRepromptService: PasswordRepromptService) {
|
||||||
super(cipherService, totpService, tokenService, i18nService, cryptoService, platformUtilsService,
|
super(cipherService, totpService, tokenService, i18nService, cryptoService, platformUtilsService,
|
||||||
auditService, window, broadcasterService, ngZone, changeDetectorRef, userService, eventService, apiService);
|
auditService, window, broadcasterService, ngZone, changeDetectorRef, userService, eventService,
|
||||||
|
apiService, passwordRepromptService);
|
||||||
}
|
}
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
@ -72,7 +74,7 @@ export class ViewComponent extends BaseViewComponent implements OnChanges {
|
|||||||
this.onViewCipherPasswordHistory.emit(this.cipher);
|
this.onViewCipherPasswordHistory.emit(this.cipher);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(value: string, typeI18nKey: string, aType: string) {
|
async copy(value: string, typeI18nKey: string, aType: string) {
|
||||||
super.copy(value, typeI18nKey, aType);
|
super.copy(value, typeI18nKey, aType);
|
||||||
this.messagingService.send('minimizeOnCopy');
|
this.messagingService.send('minimizeOnCopy');
|
||||||
}
|
}
|
||||||
|
@ -1668,5 +1668,14 @@
|
|||||||
},
|
},
|
||||||
"emailVerificationRequiredDesc": {
|
"emailVerificationRequiredDesc": {
|
||||||
"message": "You must verify your email to use this feature."
|
"message": "You must verify your email to use this feature."
|
||||||
|
},
|
||||||
|
"passwordPrompt": {
|
||||||
|
"message": "Master password re-prompt"
|
||||||
|
},
|
||||||
|
"passwordConfirmation": {
|
||||||
|
"message": "Master password confirmation"
|
||||||
|
},
|
||||||
|
"passwordConfirmationDesc": {
|
||||||
|
"message": "This action is protected. To continue, please re-enter your master password to verify your identity."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,4 +203,8 @@ $fa-font-path: "~font-awesome/fonts";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.swal2-validation-message {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
42
src/services/electronPlatformUtils.service.ts
Normal file
42
src/services/electronPlatformUtils.service.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import Swal from 'sweetalert2';
|
||||||
|
|
||||||
|
import { I18nService } from 'jslib/abstractions/i18n.service';
|
||||||
|
import { MessagingService } from 'jslib/abstractions/messaging.service';
|
||||||
|
import { StorageService } from 'jslib/abstractions/storage.service';
|
||||||
|
import {
|
||||||
|
ElectronPlatformUtilsService as BaseElectronPlatformUtilsService
|
||||||
|
} from 'jslib/electron/services/electronPlatformUtils.service';
|
||||||
|
|
||||||
|
export class ElectronPlatformUtilsService extends BaseElectronPlatformUtilsService {
|
||||||
|
|
||||||
|
constructor(i18nService: I18nService, messagingService: MessagingService,
|
||||||
|
isDesktopApp: boolean, storageService: StorageService) {
|
||||||
|
super(i18nService, messagingService, isDesktopApp, storageService);
|
||||||
|
}
|
||||||
|
|
||||||
|
async showPasswordDialog(title: string, body: string, passwordValidation: (value: string) => Promise<boolean>):
|
||||||
|
Promise<boolean> {
|
||||||
|
const result = await Swal.fire({
|
||||||
|
heightAuto: false,
|
||||||
|
title: title,
|
||||||
|
input: 'password',
|
||||||
|
text: body,
|
||||||
|
confirmButtonText: this.i18nService.t('ok'),
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: this.i18nService.t('cancel'),
|
||||||
|
inputAttributes: {
|
||||||
|
autocapitalize: 'off',
|
||||||
|
autocorrect: 'off',
|
||||||
|
},
|
||||||
|
inputValidator: async (value: string): Promise<any> => {
|
||||||
|
if (await passwordValidation(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.i18nService.t('invalidMasterPassword');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.isConfirmed;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user