[PS-788] - Item links use `cipherId` in query string (#2880)

* Replace 'cipherId' query param with 'itemId' for linkable ciphers
This commit is contained in:
Shane Melton 2022-06-13 07:14:09 -07:00 committed by GitHub
parent 4f9079dd4f
commit 2d72201650
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 20 deletions

View File

@ -7,7 +7,7 @@ import {
ViewChild,
ViewContainerRef,
} from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ActivatedRoute, Params, Router } from "@angular/router";
import { first } from "rxjs/operators";
import { VaultFilter } from "jslib-angular/modules/vault-filter/models/vault-filter.model";
@ -23,7 +23,6 @@ import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.se
import { StateService } from "jslib-common/abstractions/state.service";
import { SyncService } from "jslib-common/abstractions/sync.service";
import { TokenService } from "jslib-common/abstractions/token.service";
import { CipherType } from "jslib-common/enums/cipherType";
import { CipherView } from "jslib-common/models/view/cipherView";
import { UpdateKeyComponent } from "../../../../settings/update-key.component";
@ -111,9 +110,11 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
this.filterComponent.reloadOrganizations();
this.showUpdateKey = !(await this.cryptoService.hasEncKey());
if (params.cipherId) {
const cipherId = getCipherIdFromParams(params);
if (cipherId) {
const cipherView = new CipherView();
cipherView.id = params.cipherId;
cipherView.id = cipherId;
if (params.action === "clone") {
await this.cloneCipher(cipherView);
} else if (params.action === "edit") {
@ -123,9 +124,10 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
await this.ciphersComponent.reload();
this.route.queryParams.subscribe(async (params) => {
if (params.cipherId) {
if ((await this.cipherService.get(params.cipherId)) != null) {
this.editCipherId(params.cipherId);
const cipherId = getCipherIdFromParams(params);
if (cipherId) {
if ((await this.cipherService.get(cipherId)) != null) {
this.editCipherId(cipherId);
} else {
this.platformUtilsService.showToast(
"error",
@ -133,7 +135,7 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
this.i18nService.t("unknownCipher")
);
this.router.navigate([], {
queryParams: { cipherId: null },
queryParams: { itemId: null, cipherId: null },
queryParamsHandling: "merge",
});
}
@ -356,7 +358,7 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
const cipher = await this.cipherService.get(id);
if (cipher != null && cipher.reprompt != 0) {
if (!(await this.passwordRepromptService.showPasswordPrompt())) {
this.go({ cipherId: null });
this.go({ cipherId: null, itemId: null });
return;
}
}
@ -382,7 +384,7 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
);
modal.onClosedPromise().then(() => {
this.go({ cipherId: null });
this.go({ cipherId: null, itemId: null });
});
return childComponent;
@ -416,3 +418,11 @@ export class IndividualVaultComponent implements OnInit, OnDestroy {
});
}
}
/**
* Allows backwards compatibility with
* old links that used the original `cipherId` param
*/
const getCipherIdFromParams = (params: Params): string => {
return params["itemId"] || params["cipherId"];
};

View File

@ -7,7 +7,7 @@ import {
ViewChild,
ViewContainerRef,
} from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ActivatedRoute, Params, Router } from "@angular/router";
import { first } from "rxjs/operators";
import { VaultFilter } from "jslib-angular/modules/vault-filter/models/vault-filter.model";
@ -127,13 +127,14 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
}
this.route.queryParams.subscribe(async (params) => {
if (params.cipherId) {
const cipherId = getCipherIdFromParams(params);
if (cipherId) {
if (
// Handle users with implicit collection access since they use the admin endpoint
this.organization.canEditAnyCollection ||
(await this.cipherService.get(params.cipherId)) != null
(await this.cipherService.get(cipherId)) != null
) {
this.editCipherId(params.cipherId);
this.editCipherId(cipherId);
} else {
this.platformUtilsService.showToast(
"error",
@ -141,7 +142,7 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
this.i18nService.t("unknownCipher")
);
this.router.navigate([], {
queryParams: { cipherId: null },
queryParams: { cipherId: null, itemId: null },
queryParamsHandling: "merge",
});
}
@ -273,7 +274,7 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
const cipher = await this.cipherService.get(cipherId);
if (cipher != null && cipher.reprompt != 0) {
if (!(await this.passwordRepromptService.showPasswordPrompt())) {
this.go({ cipherId: null });
this.go({ cipherId: null, itemId: null });
return;
}
}
@ -300,7 +301,7 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
);
modal.onClosedPromise().then(() => {
this.go({ cipherId: null });
this.go({ cipherId: null, itemId: null });
});
return childComponent;
@ -353,3 +354,11 @@ export class OrganizationVaultComponent implements OnInit, OnDestroy {
});
}
}
/**
* Allows backwards compatibility with
* old links that used the original `cipherId` param
*/
const getCipherIdFromParams = (params: Params): string => {
return params["itemId"] || params["cipherId"];
};

View File

@ -41,10 +41,12 @@ export class PermissionsGuard implements CanActivate {
if (permissions != null && !org.hasAnyPermission(permissions)) {
// Handle linkable ciphers for organizations the user only has view access to
// https://bitwarden.atlassian.net/browse/EC-203
if (state.root.queryParamMap.has("cipherId")) {
const cipherId =
state.root.queryParamMap.get("itemId") || state.root.queryParamMap.get("cipherId");
if (cipherId) {
return this.router.createUrlTree(["/vault"], {
queryParams: {
cipherId: state.root.queryParamMap.get("cipherId"),
itemId: cipherId,
},
});
}

View File

@ -19,7 +19,7 @@
<a
appStopProp
[routerLink]="[]"
[queryParams]="{ cipherId: c.id }"
[queryParams]="{ itemId: c.id }"
queryParamsHandling="merge"
title="{{ 'editItem' | i18n }}"
>{{ c.name }}</a