mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-19 14:49:13 +01:00
[EC-143] [BEEEP] Allow linking to ciphers (#1579)
Co-authored-by: Matt Gibson <mgibson@bitwarden.com>
This commit is contained in:
parent
705251fbe2
commit
0444b78ad1
@ -24,7 +24,11 @@
|
|||||||
<p>{{ "joinProviderDesc" | i18n }}</p>
|
<p>{{ "joinProviderDesc" | i18n }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a routerLink="/" [queryParams]="{ email: email }" class="btn btn-primary btn-block">
|
<a
|
||||||
|
routerLink="/login"
|
||||||
|
[queryParams]="{ email: email }"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
{{ "logIn" | i18n }}
|
{{ "logIn" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
|
@ -20,7 +20,11 @@
|
|||||||
<p>{{ "setupProviderLoginDesc" | i18n }}</p>
|
<p>{{ "setupProviderLoginDesc" | i18n }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a routerLink="/" [queryParams]="{ email: email }" class="btn btn-primary btn-block">
|
<a
|
||||||
|
routerLink="/login"
|
||||||
|
[queryParams]="{ email: email }"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
{{ "logIn" | i18n }}
|
{{ "logIn" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
2
jslib
2
jslib
@ -1 +1 @@
|
|||||||
Subproject commit 6bcadc4f408db2c150753f53a07d6f8888b6e9ff
|
Subproject commit f6e3481fe96690a3c52f7701d92b4e57f69f976a
|
@ -23,7 +23,11 @@
|
|||||||
<p>{{ "acceptEmergencyAccess" | i18n }}</p>
|
<p>{{ "acceptEmergencyAccess" | i18n }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a routerLink="/" [queryParams]="{ email: email }" class="btn btn-primary btn-block">
|
<a
|
||||||
|
routerLink="/login"
|
||||||
|
[queryParams]="{ email: email }"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
{{ "logIn" | i18n }}
|
{{ "logIn" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
|
@ -24,7 +24,11 @@
|
|||||||
<p>{{ "joinOrganizationDesc" | i18n }}</p>
|
<p>{{ "joinOrganizationDesc" | i18n }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a routerLink="/" [queryParams]="{ email: email }" class="btn btn-primary btn-block">
|
<a
|
||||||
|
routerLink="/login"
|
||||||
|
[queryParams]="{ email: email }"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
{{ "logIn" | i18n }}
|
{{ "logIn" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,7 +58,7 @@ export class LockComponent extends BaseLockComponent {
|
|||||||
if (previousUrl !== "/" && previousUrl.indexOf("lock") === -1) {
|
if (previousUrl !== "/" && previousUrl.indexOf("lock") === -1) {
|
||||||
this.successRoute = previousUrl;
|
this.successRoute = previousUrl;
|
||||||
}
|
}
|
||||||
this.router.navigate([this.successRoute]);
|
this.router.navigateByUrl(this.successRoute);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import { ListResponse } from "jslib-common/models/response/listResponse";
|
|||||||
import { PolicyResponse } from "jslib-common/models/response/policyResponse";
|
import { PolicyResponse } from "jslib-common/models/response/policyResponse";
|
||||||
|
|
||||||
import { StateService } from "../../abstractions/state.service";
|
import { StateService } from "../../abstractions/state.service";
|
||||||
|
import { RouterService } from "../services/router.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-login",
|
selector: "app-login",
|
||||||
@ -44,7 +45,8 @@ export class LoginComponent extends BaseLoginComponent {
|
|||||||
logService: LogService,
|
logService: LogService,
|
||||||
ngZone: NgZone,
|
ngZone: NgZone,
|
||||||
protected stateService: StateService,
|
protected stateService: StateService,
|
||||||
private messagingService: MessagingService
|
private messagingService: MessagingService,
|
||||||
|
private routerService: RouterService
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
authService,
|
authService,
|
||||||
@ -70,21 +72,20 @@ export class LoginComponent extends BaseLoginComponent {
|
|||||||
this.email = qParams.email;
|
this.email = qParams.email;
|
||||||
}
|
}
|
||||||
if (qParams.premium != null) {
|
if (qParams.premium != null) {
|
||||||
this.stateService.setLoginRedirect({ route: "/settings/premium" });
|
this.routerService.setPreviousUrl("/settings/premium");
|
||||||
} else if (qParams.org != null) {
|
} else if (qParams.org != null) {
|
||||||
this.stateService.setLoginRedirect({
|
const route = this.router.createUrlTree(["settings/create-organization"], {
|
||||||
route: "/settings/create-organization",
|
queryParams: { plan: qParams.org },
|
||||||
qParams: { plan: qParams.org },
|
|
||||||
});
|
});
|
||||||
|
this.routerService.setPreviousUrl(route.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are they coming from an email for sponsoring a families organization
|
// Are they coming from an email for sponsoring a families organization
|
||||||
if (qParams.sponsorshipToken != null) {
|
if (qParams.sponsorshipToken != null) {
|
||||||
// After logging in redirect them to setup the families sponsorship
|
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
|
||||||
this.stateService.setLoginRedirect({
|
queryParams: { plan: qParams.sponsorshipToken },
|
||||||
route: "/setup/families-for-enterprise",
|
|
||||||
qParams: { token: qParams.sponsorshipToken },
|
|
||||||
});
|
});
|
||||||
|
this.routerService.setPreviousUrl(route.toString());
|
||||||
}
|
}
|
||||||
await super.ngOnInit();
|
await super.ngOnInit();
|
||||||
this.rememberEmail = await this.stateService.getRememberEmail();
|
this.rememberEmail = await this.stateService.getRememberEmail();
|
||||||
@ -145,10 +146,9 @@ export class LoginComponent extends BaseLoginComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loginRedirect = await this.stateService.getLoginRedirect();
|
const previousUrl = this.routerService.getPreviousUrl();
|
||||||
if (loginRedirect != null) {
|
if (previousUrl) {
|
||||||
this.router.navigate([loginRedirect.route], { queryParams: loginRedirect.qParams });
|
this.router.navigateByUrl(previousUrl);
|
||||||
await this.stateService.setLoginRedirect(null);
|
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate([this.successRoute]);
|
this.router.navigate([this.successRoute]);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -258,7 +258,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,6 +18,8 @@ import { MasterPasswordPolicyOptions } from "jslib-common/models/domain/masterPa
|
|||||||
import { Policy } from "jslib-common/models/domain/policy";
|
import { Policy } from "jslib-common/models/domain/policy";
|
||||||
import { ReferenceEventRequest } from "jslib-common/models/request/referenceEventRequest";
|
import { ReferenceEventRequest } from "jslib-common/models/request/referenceEventRequest";
|
||||||
|
|
||||||
|
import { RouterService } from "../services/router.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-register",
|
selector: "app-register",
|
||||||
templateUrl: "register.component.html",
|
templateUrl: "register.component.html",
|
||||||
@ -41,7 +43,8 @@ export class RegisterComponent extends BaseRegisterComponent {
|
|||||||
passwordGenerationService: PasswordGenerationService,
|
passwordGenerationService: PasswordGenerationService,
|
||||||
private policyService: PolicyService,
|
private policyService: PolicyService,
|
||||||
environmentService: EnvironmentService,
|
environmentService: EnvironmentService,
|
||||||
logService: LogService
|
logService: LogService,
|
||||||
|
private routerService: RouterService
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
authService,
|
authService,
|
||||||
@ -64,14 +67,14 @@ export class RegisterComponent extends BaseRegisterComponent {
|
|||||||
this.email = qParams.email;
|
this.email = qParams.email;
|
||||||
}
|
}
|
||||||
if (qParams.premium != null) {
|
if (qParams.premium != null) {
|
||||||
this.stateService.setLoginRedirect({ route: "/settings/premium" });
|
this.routerService.setPreviousUrl("/settings/premium");
|
||||||
} else if (qParams.org != null) {
|
} else if (qParams.org != null) {
|
||||||
this.showCreateOrgMessage = true;
|
this.showCreateOrgMessage = true;
|
||||||
this.referenceData.flow = qParams.org;
|
this.referenceData.flow = qParams.org;
|
||||||
this.stateService.setLoginRedirect({
|
const route = this.router.createUrlTree(["settings/create-organization"], {
|
||||||
route: "/settings/create-organization",
|
queryParams: { plan: qParams.org },
|
||||||
qParams: { plan: qParams.org },
|
|
||||||
});
|
});
|
||||||
|
this.routerService.setPreviousUrl(route.toString());
|
||||||
}
|
}
|
||||||
if (qParams.layout != null) {
|
if (qParams.layout != null) {
|
||||||
this.layout = this.referenceData.layout = qParams.layout;
|
this.layout = this.referenceData.layout = qParams.layout;
|
||||||
@ -88,10 +91,10 @@ export class RegisterComponent extends BaseRegisterComponent {
|
|||||||
// Are they coming from an email for sponsoring a families organization
|
// Are they coming from an email for sponsoring a families organization
|
||||||
if (qParams.sponsorshipToken != null) {
|
if (qParams.sponsorshipToken != null) {
|
||||||
// After logging in redirect them to setup the families sponsorship
|
// After logging in redirect them to setup the families sponsorship
|
||||||
this.stateService.setLoginRedirect({
|
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
|
||||||
route: "/setup/families-for-enterprise",
|
queryParams: { plan: qParams.sponsorshipToken },
|
||||||
qParams: { token: qParams.sponsorshipToken },
|
|
||||||
});
|
});
|
||||||
|
this.routerService.setPreviousUrl(route.toString());
|
||||||
}
|
}
|
||||||
if (this.referenceData.id === "") {
|
if (this.referenceData.id === "") {
|
||||||
this.referenceData.id = null;
|
this.referenceData.id = null;
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -138,7 +138,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,6 +13,8 @@ import { StateService } from "jslib-common/abstractions/state.service";
|
|||||||
import { TwoFactorService } from "jslib-common/abstractions/twoFactor.service";
|
import { TwoFactorService } from "jslib-common/abstractions/twoFactor.service";
|
||||||
import { TwoFactorProviderType } from "jslib-common/enums/twoFactorProviderType";
|
import { TwoFactorProviderType } from "jslib-common/enums/twoFactorProviderType";
|
||||||
|
|
||||||
|
import { RouterService } from "../services/router.service";
|
||||||
|
|
||||||
import { TwoFactorOptionsComponent } from "./two-factor-options.component";
|
import { TwoFactorOptionsComponent } from "./two-factor-options.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -34,7 +36,8 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
|||||||
private modalService: ModalService,
|
private modalService: ModalService,
|
||||||
route: ActivatedRoute,
|
route: ActivatedRoute,
|
||||||
logService: LogService,
|
logService: LogService,
|
||||||
twoFactorService: TwoFactorService
|
twoFactorService: TwoFactorService,
|
||||||
|
private routerService: RouterService
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
authService,
|
authService,
|
||||||
@ -70,10 +73,9 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async goAfterLogIn() {
|
async goAfterLogIn() {
|
||||||
const loginRedirect = await this.stateService.getLoginRedirect();
|
const previousUrl = this.routerService.getPreviousUrl();
|
||||||
if (loginRedirect != null) {
|
if (previousUrl) {
|
||||||
this.router.navigate([loginRedirect.route], { queryParams: loginRedirect.qParams });
|
this.router.navigateByUrl(previousUrl);
|
||||||
await this.stateService.setLoginRedirect(null);
|
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate([this.successRoute], {
|
this.router.navigate([this.successRoute], {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<a routerLink="/" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
<a routerLink="/login" class="btn btn-outline-secondary btn-block ml-2 mt-0">
|
||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -91,11 +91,17 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
this.ngZone.run(async () => {
|
this.ngZone.run(async () => {
|
||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
case "loggedIn":
|
case "loggedIn":
|
||||||
|
this.notificationsService.updateConnection(false);
|
||||||
|
break;
|
||||||
case "loggedOut":
|
case "loggedOut":
|
||||||
|
this.routerService.setPreviousUrl(null);
|
||||||
|
this.notificationsService.updateConnection(false);
|
||||||
|
break;
|
||||||
case "unlocked":
|
case "unlocked":
|
||||||
this.notificationsService.updateConnection(false);
|
this.notificationsService.updateConnection(false);
|
||||||
break;
|
break;
|
||||||
case "authBlocked":
|
case "authBlocked":
|
||||||
|
this.routerService.setPreviousUrl(message.url);
|
||||||
this.router.navigate(["/"]);
|
this.router.navigate(["/"]);
|
||||||
break;
|
break;
|
||||||
case "logout":
|
case "logout":
|
||||||
@ -109,7 +115,7 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
this.router.navigate(["lock"]);
|
this.router.navigate(["lock"]);
|
||||||
break;
|
break;
|
||||||
case "lockedUrl":
|
case "lockedUrl":
|
||||||
window.setTimeout(() => this.routerService.setPreviousUrl(message.url), 500);
|
this.routerService.setPreviousUrl(message.url);
|
||||||
break;
|
break;
|
||||||
case "syncStarted":
|
case "syncStarted":
|
||||||
break;
|
break;
|
||||||
|
@ -30,7 +30,6 @@ export abstract class BaseAcceptComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
this.route.queryParams.pipe(first()).subscribe(async (qParams) => {
|
||||||
await this.stateService.setLoginRedirect(null);
|
|
||||||
let error = this.requiredParameters.some((e) => qParams?.[e] == null || qParams[e] === "");
|
let error = this.requiredParameters.some((e) => qParams?.[e] == null || qParams[e] === "");
|
||||||
let errorMessage: string = null;
|
let errorMessage: string = null;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
@ -44,11 +43,6 @@ export abstract class BaseAcceptComponent implements OnInit {
|
|||||||
errorMessage = e.message;
|
errorMessage = e.message;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await this.stateService.setLoginRedirect({
|
|
||||||
route: this.getRedirectRoute(),
|
|
||||||
qParams: qParams,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.email = qParams.email;
|
this.email = qParams.email;
|
||||||
await this.unauthedHandler(qParams);
|
await this.unauthedHandler(qParams);
|
||||||
}
|
}
|
||||||
@ -66,10 +60,4 @@ export abstract class BaseAcceptComponent implements OnInit {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getRedirectRoute() {
|
|
||||||
const urlTree = this.router.parseUrl(this.router.url);
|
|
||||||
urlTree.queryParams = {};
|
|
||||||
return urlTree.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
24
src/app/guards/home.guard.ts
Normal file
24
src/app/guards/home.guard.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { ActivatedRouteSnapshot, CanActivate, Router } from "@angular/router";
|
||||||
|
|
||||||
|
import { StateService } from "jslib-common/abstractions/state.service";
|
||||||
|
import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class HomeGuard implements CanActivate {
|
||||||
|
constructor(
|
||||||
|
private vaultTimeoutService: VaultTimeoutService,
|
||||||
|
private router: Router,
|
||||||
|
private stateService: StateService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(route: ActivatedRouteSnapshot) {
|
||||||
|
if (!(await this.stateService.getIsAuthenticated())) {
|
||||||
|
return this.router.createUrlTree(["/login"], { queryParams: route.queryParams });
|
||||||
|
}
|
||||||
|
if (await this.vaultTimeoutService.isLocked()) {
|
||||||
|
return this.router.createUrlTree(["/lock"], { queryParams: route.queryParams });
|
||||||
|
}
|
||||||
|
return this.router.createUrlTree(["/vault"], { queryParams: route.queryParams });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<div class="mt-5 d-flex justify-content-center" *ngIf="loading">
|
||||||
|
<div>
|
||||||
|
<img class="mb-4 logo logo-themed" alt="Bitwarden" />
|
||||||
|
<p class="text-center">
|
||||||
|
<i
|
||||||
|
class="bwi bwi-spinner bwi-spin bwi-2x text-muted"
|
||||||
|
title="{{ 'loading' | i18n }}"
|
||||||
|
aria-hidden="true"
|
||||||
|
></i>
|
||||||
|
<span class="sr-only">{{ "loading" | i18n }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,26 @@
|
|||||||
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
|
import { BaseAcceptComponent } from "src/app/common/base.accept.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-accept-family-sponsorship",
|
||||||
|
templateUrl: "accept-family-sponsorship.component.html",
|
||||||
|
})
|
||||||
|
export class AcceptFamilySponsorshipComponent extends BaseAcceptComponent {
|
||||||
|
failedShortMessage = "inviteAcceptFailedShort";
|
||||||
|
failedMessage = "inviteAcceptFailed";
|
||||||
|
|
||||||
|
requiredParameters = ["email", "token"];
|
||||||
|
|
||||||
|
async authedHandler(qParams: any) {
|
||||||
|
this.router.navigate(["/setup/families-for-enterprise"], { queryParams: qParams });
|
||||||
|
}
|
||||||
|
|
||||||
|
async unauthedHandler(qParams: any) {
|
||||||
|
if (!qParams.register) {
|
||||||
|
this.router.navigate(["/login"], { queryParams: { email: qParams.email } });
|
||||||
|
} else {
|
||||||
|
this.router.navigate(["/register"], { queryParams: { email: qParams.email } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ import { first } from "rxjs/operators";
|
|||||||
|
|
||||||
import { ModalService } from "jslib-angular/services/modal.service";
|
import { ModalService } from "jslib-angular/services/modal.service";
|
||||||
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
||||||
|
import { CipherService } from "jslib-common/abstractions/cipher.service";
|
||||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||||
import { MessagingService } from "jslib-common/abstractions/messaging.service";
|
import { MessagingService } from "jslib-common/abstractions/messaging.service";
|
||||||
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
||||||
@ -64,7 +65,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private broadcasterService: BroadcasterService,
|
private broadcasterService: BroadcasterService,
|
||||||
private ngZone: NgZone,
|
private ngZone: NgZone,
|
||||||
private platformUtilsService: PlatformUtilsService
|
private platformUtilsService: PlatformUtilsService,
|
||||||
|
private cipherService: CipherService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -126,6 +128,24 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.viewEvents(cipher[0]);
|
this.viewEvents(cipher[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.route.queryParams.subscribe(async (params) => {
|
||||||
|
if (params.cipherId) {
|
||||||
|
if ((await this.cipherService.get(params.cipherId)) != null) {
|
||||||
|
this.editCipherId(params.cipherId);
|
||||||
|
} else {
|
||||||
|
this.platformUtilsService.showToast(
|
||||||
|
"error",
|
||||||
|
this.i18nService.t("errorOccurred"),
|
||||||
|
this.i18nService.t("unknownCipher")
|
||||||
|
);
|
||||||
|
this.router.navigate([], {
|
||||||
|
queryParams: { cipherId: null },
|
||||||
|
queryParamsHandling: "merge",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -257,12 +277,16 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async editCipher(cipher: CipherView) {
|
async editCipher(cipher: CipherView) {
|
||||||
|
return this.editCipherId(cipher?.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async editCipherId(cipherId: string) {
|
||||||
const [modal, childComponent] = await this.modalService.openViewRef(
|
const [modal, childComponent] = await this.modalService.openViewRef(
|
||||||
AddEditComponent,
|
AddEditComponent,
|
||||||
this.cipherAddEditModalRef,
|
this.cipherAddEditModalRef,
|
||||||
(comp) => {
|
(comp) => {
|
||||||
comp.organization = this.organization;
|
comp.organization = this.organization;
|
||||||
comp.cipherId = cipher == null ? null : cipher.id;
|
comp.cipherId = cipherId;
|
||||||
comp.onSavedCipher.subscribe(async () => {
|
comp.onSavedCipher.subscribe(async () => {
|
||||||
modal.close();
|
modal.close();
|
||||||
await this.ciphersComponent.refresh();
|
await this.ciphersComponent.refresh();
|
||||||
@ -278,6 +302,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
modal.onClosedPromise().then(() => {
|
||||||
|
this.route.params;
|
||||||
|
this.router.navigate([], { queryParams: { cipherId: null }, queryParamsHandling: "merge" });
|
||||||
|
});
|
||||||
|
|
||||||
return childComponent;
|
return childComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,6 +350,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.router.navigate([], {
|
this.router.navigate([], {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: queryParams,
|
queryParams: queryParams,
|
||||||
|
queryParamsHandling: "merge",
|
||||||
replaceUrl: true,
|
replaceUrl: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import { UpdatePasswordComponent } from "./accounts/update-password.component";
|
|||||||
import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.component";
|
import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.component";
|
||||||
import { VerifyEmailTokenComponent } from "./accounts/verify-email-token.component";
|
import { VerifyEmailTokenComponent } from "./accounts/verify-email-token.component";
|
||||||
import { VerifyRecoverDeleteComponent } from "./accounts/verify-recover-delete.component";
|
import { VerifyRecoverDeleteComponent } from "./accounts/verify-recover-delete.component";
|
||||||
|
import { HomeGuard } from "./guards/home.guard";
|
||||||
import { FrontendLayoutComponent } from "./layouts/frontend-layout.component";
|
import { FrontendLayoutComponent } from "./layouts/frontend-layout.component";
|
||||||
import { OrganizationLayoutComponent } from "./layouts/organization-layout.component";
|
import { OrganizationLayoutComponent } from "./layouts/organization-layout.component";
|
||||||
import { UserLayoutComponent } from "./layouts/user-layout.component";
|
import { UserLayoutComponent } from "./layouts/user-layout.component";
|
||||||
@ -36,6 +37,7 @@ import { OrganizationBillingComponent } from "./organizations/settings/organizat
|
|||||||
import { OrganizationSubscriptionComponent } from "./organizations/settings/organization-subscription.component";
|
import { OrganizationSubscriptionComponent } from "./organizations/settings/organization-subscription.component";
|
||||||
import { SettingsComponent as OrgSettingsComponent } from "./organizations/settings/settings.component";
|
import { SettingsComponent as OrgSettingsComponent } from "./organizations/settings/settings.component";
|
||||||
import { TwoFactorSetupComponent as OrgTwoFactorSetupComponent } from "./organizations/settings/two-factor-setup.component";
|
import { TwoFactorSetupComponent as OrgTwoFactorSetupComponent } from "./organizations/settings/two-factor-setup.component";
|
||||||
|
import { AcceptFamilySponsorshipComponent } from "./organizations/sponsorships/accept-family-sponsorship.component";
|
||||||
import { FamiliesForEnterpriseSetupComponent } from "./organizations/sponsorships/families-for-enterprise-setup.component";
|
import { FamiliesForEnterpriseSetupComponent } from "./organizations/sponsorships/families-for-enterprise-setup.component";
|
||||||
import { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
|
import { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
|
||||||
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
|
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
|
||||||
@ -73,8 +75,15 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
component: FrontendLayoutComponent,
|
component: FrontendLayoutComponent,
|
||||||
|
data: { doNotSaveUrl: true },
|
||||||
children: [
|
children: [
|
||||||
{ path: "", pathMatch: "full", component: LoginComponent, canActivate: [UnauthGuardService] },
|
{
|
||||||
|
path: "",
|
||||||
|
pathMatch: "full",
|
||||||
|
children: [], // Children lets us have an empty component.
|
||||||
|
canActivate: [HomeGuard], // Redirects either to vault, login or lock page.
|
||||||
|
},
|
||||||
|
{ path: "login", component: LoginComponent, canActivate: [UnauthGuardService] },
|
||||||
{ path: "2fa", component: TwoFactorComponent, canActivate: [UnauthGuardService] },
|
{ path: "2fa", component: TwoFactorComponent, canActivate: [UnauthGuardService] },
|
||||||
{
|
{
|
||||||
path: "register",
|
path: "register",
|
||||||
@ -108,12 +117,17 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: "accept-organization",
|
path: "accept-organization",
|
||||||
component: AcceptOrganizationComponent,
|
component: AcceptOrganizationComponent,
|
||||||
data: { titleId: "joinOrganization" },
|
data: { titleId: "joinOrganization", doNotSaveUrl: false },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "accept-emergency",
|
path: "accept-emergency",
|
||||||
component: AcceptEmergencyComponent,
|
component: AcceptEmergencyComponent,
|
||||||
data: { titleId: "acceptEmergency" },
|
data: { titleId: "acceptEmergency", doNotSaveUrl: false },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "accept-families-for-enterprise",
|
||||||
|
component: AcceptFamilySponsorshipComponent,
|
||||||
|
data: { titleId: "acceptFamilySponsorship", doNotSaveUrl: false },
|
||||||
},
|
},
|
||||||
{ path: "recover", pathMatch: "full", redirectTo: "recover-2fa" },
|
{ path: "recover", pathMatch: "full", redirectTo: "recover-2fa" },
|
||||||
{
|
{
|
||||||
|
@ -122,6 +122,7 @@ import { OrganizationBillingComponent } from "./organizations/settings/organizat
|
|||||||
import { OrganizationSubscriptionComponent } from "./organizations/settings/organization-subscription.component";
|
import { OrganizationSubscriptionComponent } from "./organizations/settings/organization-subscription.component";
|
||||||
import { SettingsComponent as OrgSettingComponent } from "./organizations/settings/settings.component";
|
import { SettingsComponent as OrgSettingComponent } from "./organizations/settings/settings.component";
|
||||||
import { TwoFactorSetupComponent as OrgTwoFactorSetupComponent } from "./organizations/settings/two-factor-setup.component";
|
import { TwoFactorSetupComponent as OrgTwoFactorSetupComponent } from "./organizations/settings/two-factor-setup.component";
|
||||||
|
import { AcceptFamilySponsorshipComponent } from "./organizations/sponsorships/accept-family-sponsorship.component";
|
||||||
import { FamiliesForEnterpriseSetupComponent } from "./organizations/sponsorships/families-for-enterprise-setup.component";
|
import { FamiliesForEnterpriseSetupComponent } from "./organizations/sponsorships/families-for-enterprise-setup.component";
|
||||||
import { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
|
import { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
|
||||||
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
|
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
|
||||||
@ -283,6 +284,7 @@ registerLocaleData(localeZhTw, "zh-TW");
|
|||||||
declarations: [
|
declarations: [
|
||||||
PremiumBadgeComponent,
|
PremiumBadgeComponent,
|
||||||
AcceptEmergencyComponent,
|
AcceptEmergencyComponent,
|
||||||
|
AcceptFamilySponsorshipComponent,
|
||||||
AcceptOrganizationComponent,
|
AcceptOrganizationComponent,
|
||||||
AccessComponent,
|
AccessComponent,
|
||||||
AccountComponent,
|
AccountComponent,
|
||||||
|
@ -4,6 +4,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router } from "@angular/router";
|
|||||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||||
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
import { OrganizationService } from "jslib-common/abstractions/organization.service";
|
||||||
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
|
||||||
|
import { SyncService } from "jslib-common/abstractions/sync.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class OrganizationGuardService implements CanActivate {
|
export class OrganizationGuardService implements CanActivate {
|
||||||
@ -11,14 +12,19 @@ export class OrganizationGuardService implements CanActivate {
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private organizationService: OrganizationService
|
private organizationService: OrganizationService,
|
||||||
|
private syncService: SyncService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async canActivate(route: ActivatedRouteSnapshot) {
|
async canActivate(route: ActivatedRouteSnapshot) {
|
||||||
|
// TODO: We need to fix this issue once and for all.
|
||||||
|
if ((await this.syncService.getLastSync()) == null) {
|
||||||
|
await this.syncService.fullSync(false);
|
||||||
|
}
|
||||||
|
|
||||||
const org = await this.organizationService.get(route.params.organizationId);
|
const org = await this.organizationService.get(route.params.organizationId);
|
||||||
if (org == null) {
|
if (org == null) {
|
||||||
this.router.navigate(["/"]);
|
return this.router.createUrlTree(["/"]);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!org.isOwner && !org.enabled) {
|
if (!org.isOwner && !org.enabled) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
@ -26,8 +32,7 @@ export class OrganizationGuardService implements CanActivate {
|
|||||||
null,
|
null,
|
||||||
this.i18nService.t("organizationIsDisabled")
|
this.i18nService.t("organizationIsDisabled")
|
||||||
);
|
);
|
||||||
this.router.navigate(["/"]);
|
return this.router.createUrlTree(["/"]);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
import { Title } from "@angular/platform-browser";
|
import { Title } from "@angular/platform-browser";
|
||||||
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
|
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
|
||||||
|
import { filter } from "rxjs";
|
||||||
|
|
||||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||||
|
|
||||||
@ -16,31 +17,22 @@ export class RouterService {
|
|||||||
i18nService: I18nService
|
i18nService: I18nService
|
||||||
) {
|
) {
|
||||||
this.currentUrl = this.router.url;
|
this.currentUrl = this.router.url;
|
||||||
router.events.subscribe((event) => {
|
|
||||||
if (event instanceof NavigationEnd) {
|
router.events
|
||||||
this.previousUrl = this.currentUrl;
|
.pipe(filter((e) => e instanceof NavigationEnd))
|
||||||
|
.subscribe((event: NavigationEnd) => {
|
||||||
this.currentUrl = event.url;
|
this.currentUrl = event.url;
|
||||||
|
|
||||||
let title = i18nService.t("pageTitle", "Bitwarden");
|
let title = i18nService.t("pageTitle", "Bitwarden");
|
||||||
let titleId: string = null;
|
|
||||||
let rawTitle: string = null;
|
|
||||||
let child = this.activatedRoute.firstChild;
|
let child = this.activatedRoute.firstChild;
|
||||||
while (child != null) {
|
while (child.firstChild) {
|
||||||
if (child.firstChild != null) {
|
child = child.firstChild;
|
||||||
child = child.firstChild;
|
|
||||||
} else if (child.snapshot.data != null && child.snapshot.data.title != null) {
|
|
||||||
rawTitle = child.snapshot.data.title;
|
|
||||||
break;
|
|
||||||
} else if (child.snapshot.data != null && child.snapshot.data.titleId != null) {
|
|
||||||
titleId = child.snapshot.data.titleId;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
titleId = null;
|
|
||||||
rawTitle = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const titleId: string = child?.snapshot?.data?.titleId;
|
||||||
|
const rawTitle: string = child?.snapshot?.data?.title;
|
||||||
|
const updateUrl = !child?.snapshot?.data?.doNotSaveUrl ?? true;
|
||||||
|
|
||||||
if (titleId != null || rawTitle != null) {
|
if (titleId != null || rawTitle != null) {
|
||||||
const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);
|
const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);
|
||||||
if (newTitle != null && newTitle !== "") {
|
if (newTitle != null && newTitle !== "") {
|
||||||
@ -48,8 +40,10 @@ export class RouterService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.titleService.setTitle(title);
|
this.titleService.setTitle(title);
|
||||||
}
|
if (updateUrl) {
|
||||||
});
|
this.setPreviousUrl(this.currentUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getPreviousUrl() {
|
getPreviousUrl() {
|
||||||
|
@ -45,6 +45,7 @@ import { PasswordRepromptService } from "../../services/passwordReprompt.service
|
|||||||
import { StateService } from "../../services/state.service";
|
import { StateService } from "../../services/state.service";
|
||||||
import { StateMigrationService } from "../../services/stateMigration.service";
|
import { StateMigrationService } from "../../services/stateMigration.service";
|
||||||
import { WebPlatformUtilsService } from "../../services/webPlatformUtils.service";
|
import { WebPlatformUtilsService } from "../../services/webPlatformUtils.service";
|
||||||
|
import { HomeGuard } from "../guards/home.guard";
|
||||||
|
|
||||||
import { EventService } from "./event.service";
|
import { EventService } from "./event.service";
|
||||||
import { ModalService } from "./modal.service";
|
import { ModalService } from "./modal.service";
|
||||||
@ -218,6 +219,7 @@ export function initFactory(
|
|||||||
provide: PasswordRepromptServiceAbstraction,
|
provide: PasswordRepromptServiceAbstraction,
|
||||||
useClass: PasswordRepromptService,
|
useClass: PasswordRepromptService,
|
||||||
},
|
},
|
||||||
|
HomeGuard,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ServicesModule {}
|
export class ServicesModule {}
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td (click)="checkCipher(c)" class="reduced-lh wrap">
|
<td (click)="checkCipher(c)" class="reduced-lh wrap">
|
||||||
<a
|
<a
|
||||||
href="#"
|
|
||||||
appStopClick
|
|
||||||
appStopProp
|
appStopProp
|
||||||
(click)="selectCipher(c)"
|
[routerLink]="[]"
|
||||||
|
[queryParams]="{ cipherId: c.id }"
|
||||||
|
queryParamsHandling="merge"
|
||||||
title="{{ 'editItem' | i18n }}"
|
title="{{ 'editItem' | i18n }}"
|
||||||
>{{ c.name }}</a
|
>{{ c.name }}</a
|
||||||
>
|
>
|
||||||
|
@ -12,6 +12,7 @@ import { first } from "rxjs/operators";
|
|||||||
|
|
||||||
import { ModalService } from "jslib-angular/services/modal.service";
|
import { ModalService } from "jslib-angular/services/modal.service";
|
||||||
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
|
||||||
|
import { CipherService } from "jslib-common/abstractions/cipher.service";
|
||||||
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
import { CryptoService } from "jslib-common/abstractions/crypto.service";
|
||||||
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
import { I18nService } from "jslib-common/abstractions/i18n.service";
|
||||||
import { MessagingService } from "jslib-common/abstractions/messaging.service";
|
import { MessagingService } from "jslib-common/abstractions/messaging.service";
|
||||||
@ -85,7 +86,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
private ngZone: NgZone,
|
private ngZone: NgZone,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private providerService: ProviderService
|
private providerService: ProviderService,
|
||||||
|
private cipherService: CipherService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
@ -136,6 +138,24 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.route.queryParams.subscribe(async (params) => {
|
||||||
|
if (params.cipherId) {
|
||||||
|
if ((await this.cipherService.get(params.cipherId)) != null) {
|
||||||
|
this.editCipherId(params.cipherId);
|
||||||
|
} else {
|
||||||
|
this.platformUtilsService.showToast(
|
||||||
|
"error",
|
||||||
|
this.i18nService.t("errorOccurred"),
|
||||||
|
this.i18nService.t("unknownCipher")
|
||||||
|
);
|
||||||
|
this.router.navigate([], {
|
||||||
|
queryParams: { cipherId: null },
|
||||||
|
queryParamsHandling: "merge",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => {
|
||||||
this.ngZone.run(async () => {
|
this.ngZone.run(async () => {
|
||||||
switch (message.command) {
|
switch (message.command) {
|
||||||
@ -334,11 +354,15 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async editCipher(cipher: CipherView) {
|
async editCipher(cipher: CipherView) {
|
||||||
|
return this.editCipherId(cipher?.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async editCipherId(id: string) {
|
||||||
const [modal, childComponent] = await this.modalService.openViewRef(
|
const [modal, childComponent] = await this.modalService.openViewRef(
|
||||||
AddEditComponent,
|
AddEditComponent,
|
||||||
this.cipherAddEditModalRef,
|
this.cipherAddEditModalRef,
|
||||||
(comp) => {
|
(comp) => {
|
||||||
comp.cipherId = cipher == null ? null : cipher.id;
|
comp.cipherId = id;
|
||||||
comp.onSavedCipher.subscribe(async () => {
|
comp.onSavedCipher.subscribe(async () => {
|
||||||
modal.close();
|
modal.close();
|
||||||
await this.ciphersComponent.refresh();
|
await this.ciphersComponent.refresh();
|
||||||
@ -354,6 +378,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
modal.onClosedPromise().then(() => {
|
||||||
|
this.route.params;
|
||||||
|
this.router.navigate([], { queryParams: { cipherId: null }, queryParamsHandling: "merge" });
|
||||||
|
});
|
||||||
|
|
||||||
return childComponent;
|
return childComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +417,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
this.router.navigate([], {
|
this.router.navigate([], {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: queryParams,
|
queryParams: queryParams,
|
||||||
|
queryParamsHandling: "merge",
|
||||||
replaceUrl: true,
|
replaceUrl: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -4890,5 +4890,8 @@
|
|||||||
},
|
},
|
||||||
"service": {
|
"service": {
|
||||||
"message": "Service"
|
"message": "Service"
|
||||||
|
},
|
||||||
|
"unknownCipher": {
|
||||||
|
"message": "Unknown Item, you may need to login with another account to access this item."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user