mirror of
https://github.com/bitwarden/web
synced 2025-12-13 14:53:25 +00:00
Resolve org user confirm not showing error when hide fingerprint is enabled (#918)
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
|||||||
import { ToasterService } from 'angular2-toaster';
|
import { ToasterService } from 'angular2-toaster';
|
||||||
import { Angulartics2 } from 'angulartics2';
|
import { Angulartics2 } from 'angulartics2';
|
||||||
|
|
||||||
|
import { ValidationService } from 'jslib/angular/services/validation.service';
|
||||||
import { ConstantsService } from 'jslib/services/constants.service';
|
import { ConstantsService } from 'jslib/services/constants.service';
|
||||||
|
|
||||||
import { ApiService } from 'jslib/abstractions/api.service';
|
import { ApiService } from 'jslib/abstractions/api.service';
|
||||||
@@ -73,7 +74,8 @@ export class PeopleComponent implements OnInit {
|
|||||||
private platformUtilsService: PlatformUtilsService, private analytics: Angulartics2,
|
private platformUtilsService: PlatformUtilsService, private analytics: Angulartics2,
|
||||||
private toasterService: ToasterService, private cryptoService: CryptoService,
|
private toasterService: ToasterService, private cryptoService: CryptoService,
|
||||||
private userService: UserService, private router: Router,
|
private userService: UserService, private router: Router,
|
||||||
private storageService: StorageService, private searchService: SearchService) { }
|
private storageService: StorageService, private searchService: SearchService,
|
||||||
|
private validationService: ValidationService) { }
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.route.parent.parent.params.subscribe(async params => {
|
this.route.parent.parent.params.subscribe(async params => {
|
||||||
@@ -258,6 +260,21 @@ export class PeopleComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const confirmUser = async (publicKey: Uint8Array) => {
|
||||||
|
try {
|
||||||
|
this.actionPromise = this.doConfirmation(user, publicKey);
|
||||||
|
await this.actionPromise;
|
||||||
|
updateUser(this);
|
||||||
|
this.analytics.eventTrack.next({ action: 'Confirmed User' });
|
||||||
|
this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', user.name || user.email));
|
||||||
|
} catch (e) {
|
||||||
|
this.validationService.showError(e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
this.actionPromise = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (this.actionPromise != null) {
|
if (this.actionPromise != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -277,9 +294,14 @@ export class PeopleComponent implements OnInit {
|
|||||||
childComponent.organizationId = this.organizationId;
|
childComponent.organizationId = this.organizationId;
|
||||||
childComponent.organizationUserId = user != null ? user.id : null;
|
childComponent.organizationUserId = user != null ? user.id : null;
|
||||||
childComponent.userId = user != null ? user.userId : null;
|
childComponent.userId = user != null ? user.userId : null;
|
||||||
childComponent.onConfirmedUser.subscribe(() => {
|
childComponent.onConfirmedUser.subscribe(async (publicKey: Uint8Array) => {
|
||||||
|
try {
|
||||||
|
await confirmUser(publicKey);
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
updateUser(this);
|
} catch (e) {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
console.error('Handled exception:', e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.modal.onClosed.subscribe(() => {
|
this.modal.onClosed.subscribe(() => {
|
||||||
@@ -288,12 +310,19 @@ export class PeopleComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionPromise = this.doConfirmation(user);
|
try {
|
||||||
await this.actionPromise;
|
const publicKeyResponse = await this.apiService.getUserPublicKey(user.userId);
|
||||||
updateUser(this);
|
const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);
|
||||||
this.analytics.eventTrack.next({ action: 'Confirmed User' });
|
try {
|
||||||
this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', user.name || user.email));
|
// tslint:disable-next-line
|
||||||
this.actionPromise = null;
|
console.log('User\'s fingerprint: ' +
|
||||||
|
(await this.cryptoService.getFingerprint(user.userId, publicKey.buffer)).join('-'));
|
||||||
|
} catch { }
|
||||||
|
await confirmUser(publicKey);
|
||||||
|
} catch (e) {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
console.error('Handled exception:', e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async events(user: OrganizationUserUserDetailsResponse) {
|
async events(user: OrganizationUserUserDetailsResponse) {
|
||||||
@@ -334,15 +363,8 @@ export class PeopleComponent implements OnInit {
|
|||||||
return !searching && this.users && this.users.length > this.pageSize;
|
return !searching && this.users && this.users.length > this.pageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async doConfirmation(user: OrganizationUserUserDetailsResponse) {
|
private async doConfirmation(user: OrganizationUserUserDetailsResponse, publicKey: Uint8Array) {
|
||||||
const orgKey = await this.cryptoService.getOrgKey(this.organizationId);
|
const orgKey = await this.cryptoService.getOrgKey(this.organizationId);
|
||||||
const publicKeyResponse = await this.apiService.getUserPublicKey(user.userId);
|
|
||||||
const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey);
|
|
||||||
try {
|
|
||||||
// tslint:disable-next-line
|
|
||||||
console.log('User\'s fingerprint: ' +
|
|
||||||
(await this.cryptoService.getFingerprint(user.userId, publicKey.buffer)).join('-'));
|
|
||||||
} catch { }
|
|
||||||
const key = await this.cryptoService.rsaEncrypt(orgKey.key, publicKey.buffer);
|
const key = await this.cryptoService.rsaEncrypt(orgKey.key, publicKey.buffer);
|
||||||
const request = new OrganizationUserConfirmRequest();
|
const request = new OrganizationUserConfirmRequest();
|
||||||
request.key = key.encryptedString;
|
request.key = key.encryptedString;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<div class="modal fade" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="confirmUserTitle">
|
<div class="modal fade" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="confirmUserTitle">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<form class="modal-content" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
<form class="modal-content" #form (ngSubmit)="submit()">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h2 class="modal-title" id="confirmUserTitle">
|
<h2 class="modal-title" id="confirmUserTitle">
|
||||||
{{'confirmUser' | i18n}}
|
{{'confirmUser' | i18n}}
|
||||||
|
|||||||
@@ -6,18 +6,12 @@ import {
|
|||||||
Output,
|
Output,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { ToasterService } from 'angular2-toaster';
|
|
||||||
import { Angulartics2 } from 'angulartics2';
|
|
||||||
|
|
||||||
import { ConstantsService } from 'jslib/services/constants.service';
|
import { ConstantsService } from 'jslib/services/constants.service';
|
||||||
|
|
||||||
import { ApiService } from 'jslib/abstractions/api.service';
|
import { ApiService } from 'jslib/abstractions/api.service';
|
||||||
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
import { CryptoService } from 'jslib/abstractions/crypto.service';
|
||||||
import { I18nService } from 'jslib/abstractions/i18n.service';
|
|
||||||
import { StorageService } from 'jslib/abstractions/storage.service';
|
import { StorageService } from 'jslib/abstractions/storage.service';
|
||||||
|
|
||||||
import { OrganizationUserConfirmRequest } from 'jslib/models/request/organizationUserConfirmRequest';
|
|
||||||
|
|
||||||
import { Utils } from 'jslib/misc/utils';
|
import { Utils } from 'jslib/misc/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -34,13 +28,11 @@ export class UserConfirmComponent implements OnInit {
|
|||||||
dontAskAgain = false;
|
dontAskAgain = false;
|
||||||
loading = true;
|
loading = true;
|
||||||
fingerprint: string;
|
fingerprint: string;
|
||||||
formPromise: Promise<any>;
|
|
||||||
|
|
||||||
private publicKey: Uint8Array = null;
|
private publicKey: Uint8Array = null;
|
||||||
|
|
||||||
constructor(private apiService: ApiService, private i18nService: I18nService,
|
constructor(private apiService: ApiService, private cryptoService: CryptoService,
|
||||||
private analytics: Angulartics2, private toasterService: ToasterService,
|
private storageService: StorageService) { }
|
||||||
private cryptoService: CryptoService, private storageService: StorageService) { }
|
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
try {
|
try {
|
||||||
@@ -65,20 +57,6 @@ export class UserConfirmComponent implements OnInit {
|
|||||||
await this.storageService.save(ConstantsService.autoConfirmFingerprints, true);
|
await this.storageService.save(ConstantsService.autoConfirmFingerprints, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
this.onConfirmedUser.emit(this.publicKey);
|
||||||
this.formPromise = this.doConfirmation();
|
|
||||||
await this.formPromise;
|
|
||||||
this.analytics.eventTrack.next({ action: 'Confirmed User' });
|
|
||||||
this.toasterService.popAsync('success', null, this.i18nService.t('hasBeenConfirmed', this.name));
|
|
||||||
this.onConfirmedUser.emit();
|
|
||||||
} catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
private async doConfirmation() {
|
|
||||||
const orgKey = await this.cryptoService.getOrgKey(this.organizationId);
|
|
||||||
const key = await this.cryptoService.rsaEncrypt(orgKey.key, this.publicKey.buffer);
|
|
||||||
const request = new OrganizationUserConfirmRequest();
|
|
||||||
request.key = key.encryptedString;
|
|
||||||
await this.apiService.postOrganizationUserConfirm(this.organizationId, this.organizationUserId, request);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ export class WeakPasswordsReportComponent extends CipherReportComponent implemen
|
|||||||
const weakPasswordCiphers: CipherView[] = [];
|
const weakPasswordCiphers: CipherView[] = [];
|
||||||
const isUserNameNotEmpty = (c: CipherView): boolean => {
|
const isUserNameNotEmpty = (c: CipherView): boolean => {
|
||||||
return c.login.username != null && c.login.username.trim() !== '';
|
return c.login.username != null && c.login.username.trim() !== '';
|
||||||
}
|
};
|
||||||
const getCacheKey = (c:CipherView): string => {
|
const getCacheKey = (c: CipherView): string => {
|
||||||
return c.login.password + '_____' + (isUserNameNotEmpty(c) ? c.login.username : '');
|
return c.login.password + '_____' + (isUserNameNotEmpty(c) ? c.login.username : '');
|
||||||
}
|
};
|
||||||
|
|
||||||
allCiphers.forEach(c => {
|
allCiphers.forEach(c => {
|
||||||
if (c.type !== CipherType.Login || c.login.password == null || c.login.password === '' || c.isDeleted) {
|
if (c.type !== CipherType.Login || c.login.password == null || c.login.password === '' || c.isDeleted) {
|
||||||
|
|||||||
Reference in New Issue
Block a user