mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
[EC-781] User can bypass master password requirements policy by canceling password reset and pasting invite link (#4218)
* [EC-781] Forcing the user to login to evaluate if the user's password meets the Organization password policy requirements
* [EC-781] Fix bug preventing from submitting update password form
* Revert "[EC-781] Forcing the user to login to evaluate if the user's password meets the Organization password policy requirements"
This reverts commit f09d74b4fc
.
* [EC-781] Get email value from query parameters also for authenticated requests
* [EC-781] Forcing the user to login to evaluate if the user's current password meets the Organization password policy requirements
* [EC-781] Logging out the user using messagingService on accept-organization component
* [EC-781] Refactored accept-organization component to be simpler to read
This commit is contained in:
parent
2ac8e27b31
commit
bf67493663
@ -11,7 +11,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container" *ngIf="!loading && !authed">
|
<div class="container" *ngIf="!loading">
|
||||||
<div class="row justify-content-md-center mt-5">
|
<div class="row justify-content-md-center mt-5">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<p class="lead text-center mb-4">{{ "joinOrganization" | i18n }}</p>
|
<p class="lead text-center mb-4">{{ "joinOrganization" | i18n }}</p>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { ActivatedRoute, Params, Router } from "@angular/router";
|
import { ActivatedRoute, Params, Router } from "@angular/router";
|
||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|
||||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||||
|
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||||
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
import { OrganizationUserService } from "@bitwarden/common/abstractions/organization-user/organization-user.service";
|
||||||
import { OrganizationUserAcceptRequest } from "@bitwarden/common/abstractions/organization-user/requests";
|
import { OrganizationUserAcceptRequest } from "@bitwarden/common/abstractions/organization-user/requests";
|
||||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/abstractions/organization/organization-api.service.abstraction";
|
||||||
@ -31,19 +31,28 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
|||||||
platformUtilsService: PlatformUtilsService,
|
platformUtilsService: PlatformUtilsService,
|
||||||
i18nService: I18nService,
|
i18nService: I18nService,
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
private apiService: ApiService,
|
|
||||||
stateService: StateService,
|
stateService: StateService,
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private policyApiService: PolicyApiServiceAbstraction,
|
private policyApiService: PolicyApiServiceAbstraction,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
private logService: LogService,
|
private logService: LogService,
|
||||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
private organizationUserService: OrganizationUserService
|
private organizationUserService: OrganizationUserService,
|
||||||
|
private messagingService: MessagingService
|
||||||
) {
|
) {
|
||||||
super(router, platformUtilsService, i18nService, route, stateService);
|
super(router, platformUtilsService, i18nService, route, stateService);
|
||||||
}
|
}
|
||||||
|
|
||||||
async authedHandler(qParams: Params): Promise<void> {
|
async authedHandler(qParams: Params): Promise<void> {
|
||||||
|
const needsReAuth = (await this.stateService.getOrganizationInvitation()) != null;
|
||||||
|
if (!needsReAuth) {
|
||||||
|
// Accepting an org invite requires authentication from a logged out state
|
||||||
|
this.messagingService.send("logout", { redirect: false });
|
||||||
|
await this.prepareOrganizationInvitation(qParams);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User has already logged in and passed the Master Password policy check
|
||||||
this.actionPromise = this.prepareAcceptRequest(qParams).then(async (request) => {
|
this.actionPromise = this.prepareAcceptRequest(qParams).then(async (request) => {
|
||||||
await this.organizationUserService.postOrganizationUserAccept(
|
await this.organizationUserService.postOrganizationUserAccept(
|
||||||
qParams.organizationId,
|
qParams.organizationId,
|
||||||
@ -52,6 +61,7 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await this.stateService.setOrganizationInvitation(null);
|
||||||
await this.actionPromise;
|
await this.actionPromise;
|
||||||
this.platformUtilService.showToast(
|
this.platformUtilService.showToast(
|
||||||
"success",
|
"success",
|
||||||
@ -60,17 +70,11 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
|||||||
{ timeout: 10000 }
|
{ timeout: 10000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
await this.stateService.setOrganizationInvitation(null);
|
|
||||||
this.router.navigate(["/vault"]);
|
this.router.navigate(["/vault"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async unauthedHandler(qParams: Params): Promise<void> {
|
async unauthedHandler(qParams: Params): Promise<void> {
|
||||||
this.orgName = qParams.organizationName;
|
await this.prepareOrganizationInvitation(qParams);
|
||||||
if (this.orgName != null) {
|
|
||||||
// Fix URL encoding of space issue with Angular
|
|
||||||
this.orgName = this.orgName.replace(/\+/g, " ");
|
|
||||||
}
|
|
||||||
await this.stateService.setOrganizationInvitation(qParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async prepareAcceptRequest(qParams: Params): Promise<OrganizationUserAcceptRequest> {
|
private async prepareAcceptRequest(qParams: Params): Promise<OrganizationUserAcceptRequest> {
|
||||||
@ -121,4 +125,13 @@ export class AcceptOrganizationComponent extends BaseAcceptComponent {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async prepareOrganizationInvitation(qParams: Params): Promise<void> {
|
||||||
|
this.orgName = qParams.organizationName;
|
||||||
|
if (this.orgName != null) {
|
||||||
|
// Fix URL encoding of space issue with Angular
|
||||||
|
this.orgName = this.orgName.replace(/\+/g, " ");
|
||||||
|
}
|
||||||
|
await this.stateService.setOrganizationInvitation(qParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
[password]="masterPassword"
|
[password]="masterPassword"
|
||||||
[email]="email"
|
[email]="email"
|
||||||
[showText]="true"
|
[showText]="true"
|
||||||
|
(passwordStrengthResult)="getStrengthResult($event)"
|
||||||
></app-password-strength>
|
></app-password-strength>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -112,7 +112,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
this.router.navigate(["/"]);
|
this.router.navigate(["/"]);
|
||||||
break;
|
break;
|
||||||
case "logout":
|
case "logout":
|
||||||
this.logOut(!!message.expired);
|
this.logOut(!!message.expired, message.redirect);
|
||||||
break;
|
break;
|
||||||
case "lockVault":
|
case "lockVault":
|
||||||
await this.vaultTimeoutService.lock();
|
await this.vaultTimeoutService.lock();
|
||||||
@ -220,7 +220,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async logOut(expired: boolean) {
|
private async logOut(expired: boolean, redirect = true) {
|
||||||
await this.eventUploadService.uploadEvents();
|
await this.eventUploadService.uploadEvents();
|
||||||
const userId = await this.stateService.getUserId();
|
const userId = await this.stateService.getUserId();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -247,7 +247,9 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
await this.stateService.clean({ userId: userId });
|
await this.stateService.clean({ userId: userId });
|
||||||
Swal.close();
|
Swal.close();
|
||||||
this.router.navigate(["/"]);
|
if (redirect) {
|
||||||
|
this.router.navigate(["/"]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ export abstract class BaseAcceptComponent implements OnInit {
|
|||||||
let errorMessage: string = null;
|
let errorMessage: string = null;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
this.authed = await this.stateService.getIsAuthenticated();
|
this.authed = await this.stateService.getIsAuthenticated();
|
||||||
|
this.email = qParams.email;
|
||||||
|
|
||||||
if (this.authed) {
|
if (this.authed) {
|
||||||
try {
|
try {
|
||||||
@ -44,7 +45,6 @@ export abstract class BaseAcceptComponent implements OnInit {
|
|||||||
errorMessage = e.message;
|
errorMessage = e.message;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.email = qParams.email;
|
|
||||||
await this.unauthedHandler(qParams);
|
await this.unauthedHandler(qParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user