mirror of
https://github.com/bitwarden/jslib
synced 2025-12-22 03:03:15 +00:00
Merge branch 'master' into AccountService
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Directive,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
} from '@angular/core';
|
||||
|
||||
import {
|
||||
@@ -18,13 +20,17 @@ import { CipherType } from 'jslib-common/enums/cipherType';
|
||||
import { EventType } from 'jslib-common/enums/eventType';
|
||||
import { FieldType } from 'jslib-common/enums/fieldType';
|
||||
|
||||
import { Utils } from 'jslib-common/misc/utils';
|
||||
|
||||
@Directive()
|
||||
export class AddEditCustomFieldsComponent {
|
||||
export class AddEditCustomFieldsComponent implements OnChanges {
|
||||
@Input() cipher: CipherView;
|
||||
@Input() thisCipherType: CipherType;
|
||||
@Input() editMode: boolean;
|
||||
|
||||
addFieldType: FieldType = FieldType.Text;
|
||||
addFieldTypeOptions: any[];
|
||||
addFieldLinkedTypeOption: any;
|
||||
linkedFieldOptions: any[] = [];
|
||||
|
||||
cipherType = CipherType;
|
||||
@@ -37,6 +43,17 @@ export class AddEditCustomFieldsComponent {
|
||||
{ name: i18nService.t('cfTypeHidden'), value: FieldType.Hidden },
|
||||
{ name: i18nService.t('cfTypeBoolean'), value: FieldType.Boolean },
|
||||
];
|
||||
this.addFieldLinkedTypeOption = { name: this.i18nService.t('cfTypeLinked'), value: FieldType.Linked };
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.thisCipherType != null) {
|
||||
this.setLinkedFieldOptions();
|
||||
|
||||
if (!changes.thisCipherType.firstChange) {
|
||||
this.resetCipherLinkedFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addField() {
|
||||
@@ -48,6 +65,10 @@ export class AddEditCustomFieldsComponent {
|
||||
f.type = this.addFieldType;
|
||||
f.newField = true;
|
||||
|
||||
if (f.type === FieldType.Linked) {
|
||||
f.linkedId = this.linkedFieldOptions[0].value;
|
||||
}
|
||||
|
||||
this.cipher.fields.push(f);
|
||||
}
|
||||
|
||||
@@ -73,4 +94,31 @@ export class AddEditCustomFieldsComponent {
|
||||
drop(event: CdkDragDrop<string[]>) {
|
||||
moveItemInArray(this.cipher.fields, event.previousIndex, event.currentIndex);
|
||||
}
|
||||
|
||||
private setLinkedFieldOptions() {
|
||||
if (this.cipher.linkedFieldOptions == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options: any = [];
|
||||
this.cipher.linkedFieldOptions.forEach((linkedFieldOption, id) =>
|
||||
options.push({ name: this.i18nService.t(linkedFieldOption.i18nKey), value: id }));
|
||||
this.linkedFieldOptions = options.sort(Utils.getSortFunction(this.i18nService, 'name'));
|
||||
}
|
||||
|
||||
private resetCipherLinkedFields() {
|
||||
if (this.cipher.fields == null || this.cipher.fields.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete any Linked custom fields if the item type does not support them
|
||||
if (this.cipher.linkedFieldOptions == null) {
|
||||
this.cipher.fields = this.cipher.fields.filter(f => f.type !== FieldType.Linked);
|
||||
return;
|
||||
}
|
||||
|
||||
this.cipher.fields
|
||||
.filter(f => f.type = FieldType.Linked)
|
||||
.forEach(f => f.linkedId = this.linkedFieldOptions[0].value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { LogService } from 'jslib-common/abstractions/log.service';
|
||||
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
||||
import { OrganizationService } from 'jslib-common/abstractions/organization.service';
|
||||
import { PasswordRepromptService } from 'jslib-common/abstractions/passwordReprompt.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { PolicyService } from 'jslib-common/abstractions/policy.service';
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
@@ -80,6 +81,7 @@ export class AddEditComponent implements OnInit {
|
||||
currentDate = new Date();
|
||||
allowPersonal = true;
|
||||
reprompt: boolean = false;
|
||||
canUseReprompt: boolean = true;
|
||||
|
||||
protected writeableCollections: CollectionView[];
|
||||
private previousCipherId: string;
|
||||
@@ -89,7 +91,8 @@ export class AddEditComponent implements OnInit {
|
||||
protected auditService: AuditService, protected stateService: StateService,
|
||||
protected collectionService: CollectionService, protected messagingService: MessagingService,
|
||||
protected eventService: EventService, protected policyService: PolicyService,
|
||||
private logService: LogService, private organizationService: OrganizationService) {
|
||||
private logService: LogService, protected passwordRepromptService: PasswordRepromptService,
|
||||
private organizationService: OrganizationService) {
|
||||
this.typeOptions = [
|
||||
{ name: i18nService.t('typeLogin'), value: CipherType.Login },
|
||||
{ name: i18nService.t('typeCard'), value: CipherType.Card },
|
||||
@@ -169,6 +172,8 @@ export class AddEditComponent implements OnInit {
|
||||
}
|
||||
|
||||
this.writeableCollections = await this.loadCollections();
|
||||
|
||||
this.canUseReprompt = await this.passwordRepromptService.enabled();
|
||||
}
|
||||
|
||||
async load() {
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
OnInit,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { EventService } from 'jslib-common/abstractions/event.service';
|
||||
@@ -12,6 +13,7 @@ import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { LogService } from 'jslib-common/abstractions/log.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { PolicyService } from 'jslib-common/abstractions/policy.service';
|
||||
import { UserVerificationService } from 'jslib-common/abstractions/userVerification.service';
|
||||
|
||||
import { EventType } from 'jslib-common/enums/eventType';
|
||||
import { PolicyType } from 'jslib-common/enums/policyType';
|
||||
@@ -21,15 +23,24 @@ export class ExportComponent implements OnInit {
|
||||
@Output() onSaved = new EventEmitter();
|
||||
|
||||
formPromise: Promise<string>;
|
||||
masterPassword: string;
|
||||
format: 'json' | 'encrypted_json' | 'csv' = 'json';
|
||||
showPassword = false;
|
||||
disabledByPolicy: boolean = false;
|
||||
|
||||
exportForm = this.fb.group({
|
||||
format: ['json'],
|
||||
secret: [''],
|
||||
});
|
||||
|
||||
formatOptions = [
|
||||
{ name: '.json', value: 'json' },
|
||||
{ name: '.csv', value: 'csv' },
|
||||
{ name: '.json (Encrypted)', value: 'encrypted_json' },
|
||||
];
|
||||
|
||||
constructor(protected cryptoService: CryptoService, protected i18nService: I18nService,
|
||||
protected platformUtilsService: PlatformUtilsService, protected exportService: ExportService,
|
||||
protected eventService: EventService, private policyService: PolicyService, protected win: Window,
|
||||
private logService: LogService) { }
|
||||
private logService: LogService, private userVerificationService: UserVerificationService,
|
||||
private fb: FormBuilder) { }
|
||||
|
||||
async ngOnInit() {
|
||||
await this.checkExportDisabled();
|
||||
@@ -37,6 +48,9 @@ export class ExportComponent implements OnInit {
|
||||
|
||||
async checkExportDisabled() {
|
||||
this.disabledByPolicy = await this.policyService.policyAppliesToUser(PolicyType.DisablePersonalVaultExport);
|
||||
if (this.disabledByPolicy) {
|
||||
this.exportForm.disable();
|
||||
}
|
||||
}
|
||||
|
||||
get encryptedFormat() {
|
||||
@@ -49,31 +63,25 @@ export class ExportComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.masterPassword == null || this.masterPassword === '') {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('invalidMasterPassword'));
|
||||
return;
|
||||
}
|
||||
|
||||
const acceptedWarning = await this.warningDialog();
|
||||
if (!acceptedWarning) {
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordValid = await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null);
|
||||
if (passwordValid) {
|
||||
try {
|
||||
this.formPromise = this.getExportData();
|
||||
const data = await this.formPromise;
|
||||
this.downloadFile(data);
|
||||
this.saved();
|
||||
await this.collectEvent();
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
} else {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'),
|
||||
this.i18nService.t('invalidMasterPassword'));
|
||||
const secret = this.exportForm.get('secret').value;
|
||||
if (!await this.userVerificationService.verifyUser(secret)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.formPromise = this.getExportData();
|
||||
const data = await this.formPromise;
|
||||
this.downloadFile(data);
|
||||
this.saved();
|
||||
await this.collectEvent();
|
||||
this.exportForm.get('secret').setValue('');
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +101,6 @@ export class ExportComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
togglePassword() {
|
||||
this.showPassword = !this.showPassword;
|
||||
document.getElementById('masterPassword').focus();
|
||||
}
|
||||
|
||||
protected saved() {
|
||||
this.onSaved.emit();
|
||||
}
|
||||
@@ -123,6 +126,10 @@ export class ExportComponent implements OnInit {
|
||||
await this.eventService.collect(EventType.User_ClientExportedVault);
|
||||
}
|
||||
|
||||
get format() {
|
||||
return this.exportForm.get('format').value;
|
||||
}
|
||||
|
||||
private downloadFile(csv: string): void {
|
||||
const fileName = this.getFileName();
|
||||
this.platformUtilsService.saveFile(this.win, csv, { type: 'text/plain' }, fileName);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { CryptoService } from 'jslib-common/abstractions/crypto.service';
|
||||
import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { LogService } from 'jslib-common/abstractions/log.service';
|
||||
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
@@ -14,7 +15,7 @@ import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.serv
|
||||
import { EncString } from 'jslib-common/models/domain/encString';
|
||||
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
|
||||
|
||||
import { PasswordVerificationRequest } from 'jslib-common/models/request/passwordVerificationRequest';
|
||||
import { SecretVerificationRequest } from 'jslib-common/models/request/secretVerificationRequest';
|
||||
|
||||
import { Utils } from 'jslib-common/misc/utils';
|
||||
|
||||
@@ -44,7 +45,8 @@ export class LockComponent implements OnInit {
|
||||
protected platformUtilsService: PlatformUtilsService, protected messagingService: MessagingService,
|
||||
protected cryptoService: CryptoService, protected vaultTimeoutService: VaultTimeoutService,
|
||||
protected environmentService: EnvironmentService, protected stateService: StateService,
|
||||
protected apiService: ApiService, private logService: LogService) { }
|
||||
protected apiService: ApiService, private logService: LogService,
|
||||
private keyConnectorService: KeyConnectorService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.stateService.accounts.subscribe(async _accounts => {
|
||||
@@ -56,6 +58,11 @@ export class LockComponent implements OnInit {
|
||||
this.biometricText = await this.stateService.getBiometricText();
|
||||
this.email = await this.stateService.getEmail();
|
||||
|
||||
// Users with key connector and without biometric or pin has no MP to unlock using
|
||||
if (await this.keyConnectorService.getUsesKeyConnector() && !(this.biometricLock || this.pinLock)) {
|
||||
await this.vaultTimeoutService.logOut();
|
||||
}
|
||||
|
||||
const webVaultUrl = this.environmentService.getWebVaultUrl();
|
||||
const vaultUrl = webVaultUrl === 'https://vault.bitwarden.com' ? 'https://bitwarden.com' : webVaultUrl;
|
||||
this.webVaultHostname = Utils.getHostname(vaultUrl);
|
||||
@@ -117,7 +124,7 @@ export class LockComponent implements OnInit {
|
||||
if (storedKeyHash != null) {
|
||||
passwordValid = await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, key);
|
||||
} else {
|
||||
const request = new PasswordVerificationRequest();
|
||||
const request = new SecretVerificationRequest();
|
||||
const serverKeyHash = await this.cryptoService.hashPassword(this.masterPassword, key,
|
||||
HashPurpose.ServerAuthorization);
|
||||
request.masterPasswordHash = serverKeyHash;
|
||||
|
||||
77
angular/src/components/remove-password.component.ts
Normal file
77
angular/src/components/remove-password.component.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import {
|
||||
Directive,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { I18nService } from 'jslib-common/abstractions/i18n.service';
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
|
||||
import { StorageService } from 'jslib-common/abstractions/storage.service';
|
||||
import { SyncService } from 'jslib-common/abstractions/sync.service';
|
||||
import { UserService } from 'jslib-common/abstractions/user.service';
|
||||
|
||||
import { ConstantsService } from 'jslib-common/services/constants.service';
|
||||
|
||||
import { Organization } from 'jslib-common/models/domain/organization';
|
||||
|
||||
@Directive()
|
||||
export class RemovePasswordComponent implements OnInit {
|
||||
|
||||
actionPromise: Promise<any>;
|
||||
continuing: boolean = false;
|
||||
leaving: boolean = false;
|
||||
|
||||
loading: boolean = true;
|
||||
organization: Organization;
|
||||
email: string;
|
||||
|
||||
constructor(private router: Router, private userService: UserService,
|
||||
private apiService: ApiService, private syncService: SyncService,
|
||||
private platformUtilsService: PlatformUtilsService, private i18nService: I18nService,
|
||||
private keyConnectorService: KeyConnectorService, private storageService: StorageService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.organization = await this.keyConnectorService.getManagingOrganization();
|
||||
this.email = await this.userService.getEmail();
|
||||
await this.syncService.fullSync(false);
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
async convert() {
|
||||
this.continuing = true;
|
||||
this.actionPromise = this.keyConnectorService.migrateUser();
|
||||
|
||||
try {
|
||||
await this.actionPromise;
|
||||
this.platformUtilsService.showToast('success', null, this.i18nService.t('removedMasterPassword'));
|
||||
await this.keyConnectorService.removeConvertAccountRequired();
|
||||
this.router.navigate(['']);
|
||||
} catch (e) {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e.message);
|
||||
}
|
||||
}
|
||||
|
||||
async leave() {
|
||||
const confirmed = await this.platformUtilsService.showDialog(
|
||||
this.i18nService.t('leaveOrganizationConfirmation'), this.organization.name,
|
||||
this.i18nService.t('yes'), this.i18nService.t('no'), 'warning');
|
||||
if (!confirmed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.leaving = true;
|
||||
this.actionPromise = this.apiService.postLeaveOrganization(this.organization.id).then(() => {
|
||||
return this.syncService.fullSync(true);
|
||||
});
|
||||
await this.actionPromise;
|
||||
this.platformUtilsService.showToast('success', null, this.i18nService.t('leftOrganization'));
|
||||
await this.keyConnectorService.removeConvertAccountRequired();
|
||||
this.router.navigate(['']);
|
||||
} catch (e) {
|
||||
this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export class SsoComponent {
|
||||
await this.stateService.setSsoCodeVerifier(null);
|
||||
await this.stateService.setSsoState(null);
|
||||
if (qParams.code != null && codeVerifier != null && state != null && this.checkState(state, qParams.state)) {
|
||||
await this.logIn(qParams.code, codeVerifier, this.getOrgIdentiferFromState(qParams.state));
|
||||
await this.logIn(qParams.code, codeVerifier, this.getOrgIdentifierFromState(qParams.state));
|
||||
}
|
||||
} else if (qParams.clientId != null && qParams.redirectUri != null && qParams.state != null &&
|
||||
qParams.codeChallenge != null) {
|
||||
@@ -180,14 +180,14 @@ export class SsoComponent {
|
||||
}
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
if (e.message === 'Unable to reach crypto agent') {
|
||||
this.platformUtilsService.showToast('error', null, this.i18nService.t('ssoCryptoAgentUnavailable'));
|
||||
if (e.message === 'Unable to reach key connector') {
|
||||
this.platformUtilsService.showToast('error', null, this.i18nService.t('ssoKeyConnectorUnavailable'));
|
||||
}
|
||||
}
|
||||
this.loggingIn = false;
|
||||
}
|
||||
|
||||
private getOrgIdentiferFromState(state: string): string {
|
||||
private getOrgIdentifierFromState(state: string): string {
|
||||
if (state === null || state === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,9 @@ export class TwoFactorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
try {
|
||||
const request = new TwoFactorEmailRequest(this.authService.email, this.authService.masterPasswordHash);
|
||||
const request = new TwoFactorEmailRequest();
|
||||
request.email = this.authService.email;
|
||||
request.masterPasswordHash = this.authService.masterPasswordHash;
|
||||
this.emailPromise = this.apiService.postTwoFactorEmail(request);
|
||||
await this.emailPromise;
|
||||
if (doToast) {
|
||||
|
||||
18
angular/src/components/verify-master-password.component.html
Normal file
18
angular/src/components/verify-master-password.component.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<ng-container *ngIf="!usesKeyConnector">
|
||||
<label for="masterPassword">{{'masterPass' | i18n}}</label>
|
||||
<input id="masterPassword" type="password" name="MasterPasswordHash" class="form-control"
|
||||
[formControl]="secret" required appAutofocus appInputVerbatim>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="usesKeyConnector">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn btn-primary" (click)="requestOTP()" [disabled]="disableRequestOTP">
|
||||
{{'requestVerificationCode' | i18n}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="verificationCode">{{'verificationCode' | i18n}}</label>
|
||||
<input id="verificationCode" type="input" name="verificationCode" class="form-control"
|
||||
[formControl]="secret" required appAutofocus appInputVerbatim>
|
||||
</div>
|
||||
</ng-container>
|
||||
81
angular/src/components/verify-master-password.component.ts
Normal file
81
angular/src/components/verify-master-password.component.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormControl,
|
||||
NG_VALUE_ACCESSOR,
|
||||
} from '@angular/forms';
|
||||
|
||||
import { ApiService } from 'jslib-common/abstractions/api.service';
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
|
||||
import { VerificationType } from 'jslib-common/enums/verificationType';
|
||||
|
||||
import { Verification } from 'jslib-common/types/verification';
|
||||
|
||||
@Component({
|
||||
selector: 'app-verify-master-password',
|
||||
templateUrl: 'verify-master-password.component.html',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
multi: true,
|
||||
useExisting: VerifyMasterPasswordComponent,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class VerifyMasterPasswordComponent implements ControlValueAccessor, OnInit {
|
||||
usesKeyConnector: boolean = false;
|
||||
disableRequestOTP: boolean = false;
|
||||
|
||||
secret = new FormControl('');
|
||||
|
||||
private onChange: (value: Verification) => void;
|
||||
|
||||
constructor(private keyConnectorService: KeyConnectorService, private apiService: ApiService) { }
|
||||
|
||||
async ngOnInit() {
|
||||
this.usesKeyConnector = await this.keyConnectorService.getUsesKeyConnector();
|
||||
|
||||
this.secret.valueChanges.subscribe(secret => {
|
||||
if (this.onChange == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onChange({
|
||||
type: this.usesKeyConnector ? VerificationType.OTP : VerificationType.MasterPassword,
|
||||
secret: secret,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async requestOTP() {
|
||||
if (this.usesKeyConnector) {
|
||||
this.disableRequestOTP = true;
|
||||
await this.apiService.postAccountRequestOTP();
|
||||
}
|
||||
}
|
||||
|
||||
writeValue(obj: any): void {
|
||||
this.secret.setValue(obj);
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
setDisabledState?(isDisabled: boolean): void {
|
||||
this.disableRequestOTP = isDisabled;
|
||||
if (isDisabled) {
|
||||
this.secret.disable();
|
||||
} else {
|
||||
this.secret.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
RouterStateSnapshot,
|
||||
} from '@angular/router';
|
||||
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { MessagingService } from 'jslib-common/abstractions/messaging.service';
|
||||
import { StateService } from 'jslib-common/abstractions/state.service';
|
||||
import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.service';
|
||||
@@ -13,7 +14,8 @@ import { VaultTimeoutService } from 'jslib-common/abstractions/vaultTimeout.serv
|
||||
@Injectable()
|
||||
export class AuthGuardService implements CanActivate {
|
||||
constructor(private vaultTimeoutService: VaultTimeoutService, private router: Router,
|
||||
private messagingService: MessagingService, private stateService: StateService) { }
|
||||
private messagingService: MessagingService, private keyConnectorService: KeyConnectorService,
|
||||
private stateService: StateService) { }
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {
|
||||
const isAuthed = await this.stateService.getIsAuthenticated();
|
||||
@@ -31,6 +33,11 @@ export class AuthGuardService implements CanActivate {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!routerState.url.includes('remove-password') && await this.keyConnectorService.getConvertAccountRequired()) {
|
||||
this.router.navigate(['/remove-password']);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { KeyConnectorService } from 'jslib-common/abstractions/keyConnector.service';
|
||||
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from 'jslib-common/abstractions/passwordReprompt.service';
|
||||
|
||||
import { PasswordRepromptComponent } from '../components/password-reprompt.component';
|
||||
@@ -9,13 +10,17 @@ import { ModalService } from './modal.service';
|
||||
export class PasswordRepromptService implements PasswordRepromptServiceAbstraction {
|
||||
protected component = PasswordRepromptComponent;
|
||||
|
||||
constructor(private modalService: ModalService) { }
|
||||
constructor(private modalService: ModalService, private keyConnectorService: KeyConnectorService) { }
|
||||
|
||||
protectedFields() {
|
||||
return ['TOTP', 'Password', 'H_Field', 'Card Number', 'Security Code'];
|
||||
}
|
||||
|
||||
async showPasswordPrompt() {
|
||||
if (!await this.enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ref = this.modalService.open(this.component, {allowMultipleModals: true});
|
||||
|
||||
if (ref == null) {
|
||||
@@ -25,4 +30,8 @@ export class PasswordRepromptService implements PasswordRepromptServiceAbstracti
|
||||
const result = await ref.onClosedPromise();
|
||||
return result === true;
|
||||
}
|
||||
|
||||
async enabled() {
|
||||
return !await this.keyConnectorService.getUsesKeyConnector();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user