diff --git a/bitwarden_license/src/app/providers/manage/accept-provider.component.html b/bitwarden_license/src/app/providers/manage/accept-provider.component.html
index 7f34664a68..a5927cbc9a 100644
--- a/bitwarden_license/src/app/providers/manage/accept-provider.component.html
+++ b/bitwarden_license/src/app/providers/manage/accept-provider.component.html
@@ -24,7 +24,11 @@
{{ "joinProviderDesc" | i18n }}
diff --git a/src/app/accounts/register.component.html b/src/app/accounts/register.component.html
index 75d3883dcd..d86e0a4351 100644
--- a/src/app/accounts/register.component.html
+++ b/src/app/accounts/register.component.html
@@ -258,7 +258,7 @@
aria-hidden="true"
>
-
+
{{ "cancel" | i18n }}
diff --git a/src/app/accounts/register.component.ts b/src/app/accounts/register.component.ts
index b0fe063f46..fd2f3b567d 100644
--- a/src/app/accounts/register.component.ts
+++ b/src/app/accounts/register.component.ts
@@ -18,6 +18,8 @@ import { MasterPasswordPolicyOptions } from "jslib-common/models/domain/masterPa
import { Policy } from "jslib-common/models/domain/policy";
import { ReferenceEventRequest } from "jslib-common/models/request/referenceEventRequest";
+import { RouterService } from "../services/router.service";
+
@Component({
selector: "app-register",
templateUrl: "register.component.html",
@@ -41,7 +43,8 @@ export class RegisterComponent extends BaseRegisterComponent {
passwordGenerationService: PasswordGenerationService,
private policyService: PolicyService,
environmentService: EnvironmentService,
- logService: LogService
+ logService: LogService,
+ private routerService: RouterService
) {
super(
authService,
@@ -64,14 +67,14 @@ export class RegisterComponent extends BaseRegisterComponent {
this.email = qParams.email;
}
if (qParams.premium != null) {
- this.stateService.setLoginRedirect({ route: "/settings/premium" });
+ this.routerService.setPreviousUrl("/settings/premium");
} else if (qParams.org != null) {
this.showCreateOrgMessage = true;
this.referenceData.flow = qParams.org;
- this.stateService.setLoginRedirect({
- route: "/settings/create-organization",
- qParams: { plan: qParams.org },
+ const route = this.router.createUrlTree(["settings/create-organization"], {
+ queryParams: { plan: qParams.org },
});
+ this.routerService.setPreviousUrl(route.toString());
}
if (qParams.layout != null) {
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
if (qParams.sponsorshipToken != null) {
// After logging in redirect them to setup the families sponsorship
- this.stateService.setLoginRedirect({
- route: "/setup/families-for-enterprise",
- qParams: { token: qParams.sponsorshipToken },
+ const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
+ queryParams: { plan: qParams.sponsorshipToken },
});
+ this.routerService.setPreviousUrl(route.toString());
}
if (this.referenceData.id === "") {
this.referenceData.id = null;
diff --git a/src/app/accounts/sso.component.html b/src/app/accounts/sso.component.html
index 84ae47495f..f558895398 100644
--- a/src/app/accounts/sso.component.html
+++ b/src/app/accounts/sso.component.html
@@ -41,7 +41,7 @@
aria-hidden="true"
>
-
+
{{ "cancel" | i18n }}
diff --git a/src/app/accounts/two-factor.component.html b/src/app/accounts/two-factor.component.html
index 64961e98b9..835fd12e78 100644
--- a/src/app/accounts/two-factor.component.html
+++ b/src/app/accounts/two-factor.component.html
@@ -138,7 +138,7 @@
aria-hidden="true"
>
-
+
{{ "cancel" | i18n }}
diff --git a/src/app/accounts/two-factor.component.ts b/src/app/accounts/two-factor.component.ts
index 34cb40a93b..5c75577b23 100644
--- a/src/app/accounts/two-factor.component.ts
+++ b/src/app/accounts/two-factor.component.ts
@@ -13,6 +13,8 @@ import { StateService } from "jslib-common/abstractions/state.service";
import { TwoFactorService } from "jslib-common/abstractions/twoFactor.service";
import { TwoFactorProviderType } from "jslib-common/enums/twoFactorProviderType";
+import { RouterService } from "../services/router.service";
+
import { TwoFactorOptionsComponent } from "./two-factor-options.component";
@Component({
@@ -34,7 +36,8 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
private modalService: ModalService,
route: ActivatedRoute,
logService: LogService,
- twoFactorService: TwoFactorService
+ twoFactorService: TwoFactorService,
+ private routerService: RouterService
) {
super(
authService,
@@ -70,10 +73,9 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
}
async goAfterLogIn() {
- const loginRedirect = await this.stateService.getLoginRedirect();
- if (loginRedirect != null) {
- this.router.navigate([loginRedirect.route], { queryParams: loginRedirect.qParams });
- await this.stateService.setLoginRedirect(null);
+ const previousUrl = this.routerService.getPreviousUrl();
+ if (previousUrl) {
+ this.router.navigateByUrl(previousUrl);
} else {
this.router.navigate([this.successRoute], {
queryParams: {
diff --git a/src/app/accounts/verify-recover-delete.component.html b/src/app/accounts/verify-recover-delete.component.html
index 79fc2fcd78..975858ac5e 100644
--- a/src/app/accounts/verify-recover-delete.component.html
+++ b/src/app/accounts/verify-recover-delete.component.html
@@ -23,7 +23,7 @@
aria-hidden="true"
>
-
+
{{ "cancel" | i18n }}
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index cd94408f94..9e26f68078 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -91,11 +91,17 @@ export class AppComponent implements OnDestroy, OnInit {
this.ngZone.run(async () => {
switch (message.command) {
case "loggedIn":
+ this.notificationsService.updateConnection(false);
+ break;
case "loggedOut":
+ this.routerService.setPreviousUrl(null);
+ this.notificationsService.updateConnection(false);
+ break;
case "unlocked":
this.notificationsService.updateConnection(false);
break;
case "authBlocked":
+ this.routerService.setPreviousUrl(message.url);
this.router.navigate(["/"]);
break;
case "logout":
@@ -109,7 +115,7 @@ export class AppComponent implements OnDestroy, OnInit {
this.router.navigate(["lock"]);
break;
case "lockedUrl":
- window.setTimeout(() => this.routerService.setPreviousUrl(message.url), 500);
+ this.routerService.setPreviousUrl(message.url);
break;
case "syncStarted":
break;
diff --git a/src/app/common/base.accept.component.ts b/src/app/common/base.accept.component.ts
index fa3398f88b..36375fbd1e 100644
--- a/src/app/common/base.accept.component.ts
+++ b/src/app/common/base.accept.component.ts
@@ -30,7 +30,6 @@ export abstract class BaseAcceptComponent implements OnInit {
ngOnInit() {
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 errorMessage: string = null;
if (!error) {
@@ -44,11 +43,6 @@ export abstract class BaseAcceptComponent implements OnInit {
errorMessage = e.message;
}
} else {
- await this.stateService.setLoginRedirect({
- route: this.getRedirectRoute(),
- qParams: qParams,
- });
-
this.email = qParams.email;
await this.unauthedHandler(qParams);
}
@@ -66,10 +60,4 @@ export abstract class BaseAcceptComponent implements OnInit {
this.loading = false;
});
}
-
- getRedirectRoute() {
- const urlTree = this.router.parseUrl(this.router.url);
- urlTree.queryParams = {};
- return urlTree.toString();
- }
}
diff --git a/src/app/guards/home.guard.ts b/src/app/guards/home.guard.ts
new file mode 100644
index 0000000000..c7fa9402ee
--- /dev/null
+++ b/src/app/guards/home.guard.ts
@@ -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 });
+ }
+}
diff --git a/src/app/organizations/sponsorships/accept-family-sponsorship.component.html b/src/app/organizations/sponsorships/accept-family-sponsorship.component.html
new file mode 100644
index 0000000000..e7eb29a3ac
--- /dev/null
+++ b/src/app/organizations/sponsorships/accept-family-sponsorship.component.html
@@ -0,0 +1,13 @@
+
+
+
![Bitwarden]()
+
+
+ {{ "loading" | i18n }}
+
+
+
diff --git a/src/app/organizations/sponsorships/accept-family-sponsorship.component.ts b/src/app/organizations/sponsorships/accept-family-sponsorship.component.ts
new file mode 100644
index 0000000000..acbcaa85e5
--- /dev/null
+++ b/src/app/organizations/sponsorships/accept-family-sponsorship.component.ts
@@ -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 } });
+ }
+ }
+}
diff --git a/src/app/organizations/vault/vault.component.ts b/src/app/organizations/vault/vault.component.ts
index ea7d683ecb..61c8b100d1 100644
--- a/src/app/organizations/vault/vault.component.ts
+++ b/src/app/organizations/vault/vault.component.ts
@@ -12,6 +12,7 @@ import { first } from "rxjs/operators";
import { ModalService } from "jslib-angular/services/modal.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 { MessagingService } from "jslib-common/abstractions/messaging.service";
import { OrganizationService } from "jslib-common/abstractions/organization.service";
@@ -64,7 +65,8 @@ export class VaultComponent implements OnInit, OnDestroy {
private messagingService: MessagingService,
private broadcasterService: BroadcasterService,
private ngZone: NgZone,
- private platformUtilsService: PlatformUtilsService
+ private platformUtilsService: PlatformUtilsService,
+ private cipherService: CipherService
) {}
ngOnInit() {
@@ -126,6 +128,24 @@ export class VaultComponent implements OnInit, OnDestroy {
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) {
+ return this.editCipherId(cipher?.id);
+ }
+
+ async editCipherId(cipherId: string) {
const [modal, childComponent] = await this.modalService.openViewRef(
AddEditComponent,
this.cipherAddEditModalRef,
(comp) => {
comp.organization = this.organization;
- comp.cipherId = cipher == null ? null : cipher.id;
+ comp.cipherId = cipherId;
comp.onSavedCipher.subscribe(async () => {
modal.close();
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;
}
@@ -321,6 +350,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.router.navigate([], {
relativeTo: this.route,
queryParams: queryParams,
+ queryParamsHandling: "merge",
replaceUrl: true,
});
}
diff --git a/src/app/oss-routing.module.ts b/src/app/oss-routing.module.ts
index 6c408c13f1..440113bfa6 100644
--- a/src/app/oss-routing.module.ts
+++ b/src/app/oss-routing.module.ts
@@ -22,6 +22,7 @@ import { UpdatePasswordComponent } from "./accounts/update-password.component";
import { UpdateTempPasswordComponent } from "./accounts/update-temp-password.component";
import { VerifyEmailTokenComponent } from "./accounts/verify-email-token.component";
import { VerifyRecoverDeleteComponent } from "./accounts/verify-recover-delete.component";
+import { HomeGuard } from "./guards/home.guard";
import { FrontendLayoutComponent } from "./layouts/frontend-layout.component";
import { OrganizationLayoutComponent } from "./layouts/organization-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 { SettingsComponent as OrgSettingsComponent } from "./organizations/settings/settings.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 { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
@@ -73,8 +75,15 @@ const routes: Routes = [
{
path: "",
component: FrontendLayoutComponent,
+ data: { doNotSaveUrl: true },
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: "register",
@@ -108,12 +117,17 @@ const routes: Routes = [
{
path: "accept-organization",
component: AcceptOrganizationComponent,
- data: { titleId: "joinOrganization" },
+ data: { titleId: "joinOrganization", doNotSaveUrl: false },
},
{
path: "accept-emergency",
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" },
{
diff --git a/src/app/oss.module.ts b/src/app/oss.module.ts
index b4470f0e63..4be1f09486 100644
--- a/src/app/oss.module.ts
+++ b/src/app/oss.module.ts
@@ -122,6 +122,7 @@ import { OrganizationBillingComponent } from "./organizations/settings/organizat
import { OrganizationSubscriptionComponent } from "./organizations/settings/organization-subscription.component";
import { SettingsComponent as OrgSettingComponent } from "./organizations/settings/settings.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 { ExportComponent as OrgExportComponent } from "./organizations/tools/export.component";
import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "./organizations/tools/exposed-passwords-report.component";
@@ -283,6 +284,7 @@ registerLocaleData(localeZhTw, "zh-TW");
declarations: [
PremiumBadgeComponent,
AcceptEmergencyComponent,
+ AcceptFamilySponsorshipComponent,
AcceptOrganizationComponent,
AccessComponent,
AccountComponent,
diff --git a/src/app/services/organization-guard.service.ts b/src/app/services/organization-guard.service.ts
index bd999eea4e..8e883648bd 100644
--- a/src/app/services/organization-guard.service.ts
+++ b/src/app/services/organization-guard.service.ts
@@ -4,6 +4,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router } from "@angular/router";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { OrganizationService } from "jslib-common/abstractions/organization.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
+import { SyncService } from "jslib-common/abstractions/sync.service";
@Injectable()
export class OrganizationGuardService implements CanActivate {
@@ -11,14 +12,19 @@ export class OrganizationGuardService implements CanActivate {
private router: Router,
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
- private organizationService: OrganizationService
+ private organizationService: OrganizationService,
+ private syncService: SyncService
) {}
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);
if (org == null) {
- this.router.navigate(["/"]);
- return false;
+ return this.router.createUrlTree(["/"]);
}
if (!org.isOwner && !org.enabled) {
this.platformUtilsService.showToast(
@@ -26,8 +32,7 @@ export class OrganizationGuardService implements CanActivate {
null,
this.i18nService.t("organizationIsDisabled")
);
- this.router.navigate(["/"]);
- return false;
+ return this.router.createUrlTree(["/"]);
}
return true;
diff --git a/src/app/services/router.service.ts b/src/app/services/router.service.ts
index c71c1a4625..7493e2cb5a 100644
--- a/src/app/services/router.service.ts
+++ b/src/app/services/router.service.ts
@@ -1,6 +1,7 @@
import { Injectable } from "@angular/core";
import { Title } from "@angular/platform-browser";
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
+import { filter } from "rxjs";
import { I18nService } from "jslib-common/abstractions/i18n.service";
@@ -16,31 +17,22 @@ export class RouterService {
i18nService: I18nService
) {
this.currentUrl = this.router.url;
- router.events.subscribe((event) => {
- if (event instanceof NavigationEnd) {
- this.previousUrl = this.currentUrl;
+
+ router.events
+ .pipe(filter((e) => e instanceof NavigationEnd))
+ .subscribe((event: NavigationEnd) => {
this.currentUrl = event.url;
let title = i18nService.t("pageTitle", "Bitwarden");
- let titleId: string = null;
- let rawTitle: string = null;
let child = this.activatedRoute.firstChild;
- while (child != null) {
- if (child.firstChild != null) {
- 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;
- }
+ while (child.firstChild) {
+ child = child.firstChild;
}
+ 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) {
const newTitle = rawTitle != null ? rawTitle : i18nService.t(titleId);
if (newTitle != null && newTitle !== "") {
@@ -48,8 +40,10 @@ export class RouterService {
}
}
this.titleService.setTitle(title);
- }
- });
+ if (updateUrl) {
+ this.setPreviousUrl(this.currentUrl);
+ }
+ });
}
getPreviousUrl() {
diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts
index c8e95320db..cb63235825 100644
--- a/src/app/services/services.module.ts
+++ b/src/app/services/services.module.ts
@@ -45,6 +45,7 @@ import { PasswordRepromptService } from "../../services/passwordReprompt.service
import { StateService } from "../../services/state.service";
import { StateMigrationService } from "../../services/stateMigration.service";
import { WebPlatformUtilsService } from "../../services/webPlatformUtils.service";
+import { HomeGuard } from "../guards/home.guard";
import { EventService } from "./event.service";
import { ModalService } from "./modal.service";
@@ -218,6 +219,7 @@ export function initFactory(
provide: PasswordRepromptServiceAbstraction,
useClass: PasswordRepromptService,
},
+ HomeGuard,
],
})
export class ServicesModule {}
diff --git a/src/app/vault/ciphers.component.html b/src/app/vault/ciphers.component.html
index f36366b5a2..17db5838ad 100644
--- a/src/app/vault/ciphers.component.html
+++ b/src/app/vault/ciphers.component.html
@@ -17,10 +17,10 @@
{{ c.name }}
diff --git a/src/app/vault/vault.component.ts b/src/app/vault/vault.component.ts
index c3730bfabd..694f2bc656 100644
--- a/src/app/vault/vault.component.ts
+++ b/src/app/vault/vault.component.ts
@@ -12,6 +12,7 @@ import { first } from "rxjs/operators";
import { ModalService } from "jslib-angular/services/modal.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 { I18nService } from "jslib-common/abstractions/i18n.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
@@ -85,7 +86,8 @@ export class VaultComponent implements OnInit, OnDestroy {
private ngZone: NgZone,
private stateService: StateService,
private organizationService: OrganizationService,
- private providerService: ProviderService
+ private providerService: ProviderService,
+ private cipherService: CipherService
) {}
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.ngZone.run(async () => {
switch (message.command) {
@@ -334,11 +354,15 @@ export class VaultComponent implements OnInit, OnDestroy {
}
async editCipher(cipher: CipherView) {
+ return this.editCipherId(cipher?.id);
+ }
+
+ async editCipherId(id: string) {
const [modal, childComponent] = await this.modalService.openViewRef(
AddEditComponent,
this.cipherAddEditModalRef,
(comp) => {
- comp.cipherId = cipher == null ? null : cipher.id;
+ comp.cipherId = id;
comp.onSavedCipher.subscribe(async () => {
modal.close();
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;
}
@@ -388,6 +417,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.router.navigate([], {
relativeTo: this.route,
queryParams: queryParams,
+ queryParamsHandling: "merge",
replaceUrl: true,
});
}
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index 2dca55ab1c..7966776984 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -4890,5 +4890,8 @@
},
"service": {
"message": "Service"
+ },
+ "unknownCipher": {
+ "message": "Unknown Item, you may need to login with another account to access this item."
}
}
|