Skip to content

Commit

Permalink
fixing some bugs related to org and other modules
Browse files Browse the repository at this point in the history
- Clicking a link to a booking, will now set the correct orgId if present in URL and allowed
- breadcrumbs for bookings should show now
- updated some helper functions of tags, categories and workspace to scope based on orgId
  • Loading branch information
DonKoko committed Mar 6, 2024
1 parent 1598f75 commit 79a44e2
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 27 deletions.
4 changes: 4 additions & 0 deletions app/components/layout/breadcrumbs/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export function Breadcrumb({
{match?.data?.organization?.name}
</span>
) || "Not found";
} else if (match?.data?.booking) {
breadcrumb =
<span className="single-crumb">{match?.data?.booking?.name}</span> ||
"Not found";
} else {
breadcrumb =
<span className="single-crumb">{match?.data?.asset?.title}</span> ||
Expand Down
2 changes: 1 addition & 1 deletion app/emails/bookings-updates-template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function BookingUpdatesEmailTemplate({

{!hideViewButton && (
<Button
href={`${SERVER_URL}/bookings/${booking.id}`}
href={`${SERVER_URL}/bookings/${booking.id}?orgId=${booking.organizationId}`}
style={{
...styles.button,
textAlign: "center",
Expand Down
4 changes: 1 addition & 3 deletions app/modules/asset/service.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export async function getAsset({
organizationId?: Organization["id"];
userId?: User["id"];
}) {
const asset = await db.asset.findFirst({
return db.asset.findFirst({
where: { id, organizationId, userId },
include: {
category: true,
Expand Down Expand Up @@ -105,8 +105,6 @@ export async function getAsset({
},
},
});

return asset;
}

/**
Expand Down
8 changes: 5 additions & 3 deletions app/modules/booking/service.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,8 +641,10 @@ export const deleteBooking = async (
return b;
};

export const getBooking = async (booking: Pick<Booking, "id">) => {
const { id } = booking;
export const getBooking = async (
booking: Pick<Booking, "id" | "organizationId">
) => {
const { id, organizationId } = booking;

/**
* On the booking page, we need some data related to the assets added, so we know what actions are possible
Expand All @@ -652,7 +654,7 @@ export const getBooking = async (booking: Pick<Booking, "id">) => {
*/

return db.booking.findFirst({
where: { id },
where: { id, organizationId },
include: {
...commonInclude,
assets: {
Expand Down
10 changes: 8 additions & 2 deletions app/modules/category/service.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,24 +157,30 @@ export async function createCategoriesIfNotExists({

return Object.fromEntries(Array.from(categories));
}
export async function getCategory({ id }: Pick<Category, "id">) {
export async function getCategory({
id,
organizationId,
}: Pick<Category, "id" | "organizationId">) {
return db.category.findUnique({
where: {
id,
organizationId,
},
});
}

export async function updateCategory({
id,
organizationId,
name,
description,
color,
}: Pick<Category, "id" | "description" | "name" | "color">) {
}: Pick<Category, "id" | "organizationId" | "description" | "name" | "color">) {
try {
const category = await db.category.update({
where: {
id,
organizationId,
},
data: {
name,
Expand Down
17 changes: 15 additions & 2 deletions app/modules/organization/service.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@ import { db } from "~/database";
import { ShelfStackError } from "~/utils/error";
import { defaultUserCategories } from "../category/default-categories";

export const getOrganization = async ({ id }: { id: Organization["id"] }) =>
export const getOrganization = async ({
id,
userId,
}: {
id: Organization["id"];
userId: User["id"];
}) =>
db.organization.findUnique({
where: { id },
where: {
id,
owner: {
is: {
id: userId,
},
},
},
});

export const getOrganizationByUserId = async ({
Expand Down
10 changes: 8 additions & 2 deletions app/modules/tag/service.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,29 @@ export async function createTagsIfNotExists({
}
return tags;
}
export async function getTag({ id }: Pick<Tag, "id">) {
export async function getTag({
id,
organizationId,
}: Pick<Tag, "id" | "organizationId">) {
return db.tag.findUnique({
where: {
id,
organizationId,
},
});
}

export async function updateTag({
id,
organizationId,
name,
description,
}: Pick<Tag, "id" | "name" | "description">) {
}: Pick<Tag, "id" | "organizationId" | "name" | "description">) {
try {
const tag = await db.tag.update({
where: {
id,
organizationId,
},
data: {
name,
Expand Down
2 changes: 1 addition & 1 deletion app/routes/_layout+/assets.$assetId_.edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function loader({ context, request, params }: LoaderFunctionArgs) {
entity: PermissionEntity.asset,
action: PermissionAction.update,
});
const organization = await getOrganization({ id: organizationId });
const organization = await getOrganization({ id: organizationId, userId });

const id = getRequiredParam(params, "assetId");

Expand Down
2 changes: 1 addition & 1 deletion app/routes/_layout+/bookings.$bookingId.add-assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const loader = async ({
plural: "assets",
};

const booking = await getBooking({ id });
const booking = await getBooking({ id, organizationId });
if (!booking) {
throw new ShelfStackError({ message: "Booking not found" });
}
Expand Down
23 changes: 19 additions & 4 deletions app/routes/_layout+/bookings.$bookingId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,27 @@ export async function loader({ context, request, params }: LoaderFunctionArgs) {
entity: PermissionEntity.booking,
action: PermissionAction.create,
});
const bookingId = getRequiredParam(params, "bookingId");
const searchParams = getCurrentSearchParams(request);

/**
* If the org id in the params is different than the current organization id,
* we need to redirect and set the organization id in the cookie
* This is useful when the user is viewing a booking from a different organization that they are part of after clicking link in email
*/
const orgId = searchParams.get("orgId");
if (orgId && orgId !== organizationId) {
return redirect(`/bookings/${bookingId}`, {
headers: [setCookie(await setSelectedOrganizationIdCookie(orgId))],
});
}

const isSelfService = role === OrganizationRoles.SELF_SERVICE;
const booking = await getBooking({
id: getRequiredParam(params, "bookingId"),
id: bookingId,
organizationId: organizationId,
});

if (!booking) {
throw new ShelfStackError({ message: "Booking not found", status: 404 });
}
Expand Down Expand Up @@ -155,7 +171,6 @@ export async function loader({ context, request, params }: LoaderFunctionArgs) {
});
}

const searchParams = getCurrentSearchParams(request);
const { page, perPageParam } = getParamsValues(searchParams);
const cookie = await updateCookieWithPerPage(request, perPageParam);
const { perPage } = cookie;
Expand Down Expand Up @@ -193,7 +208,7 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => [
];

export const handle = {
breadcrumb: () => <span>Edit</span>,
breadcrumb: () => "single",
};

export async function action({ context, request, params }: ActionFunctionArgs) {
Expand Down Expand Up @@ -314,7 +329,7 @@ export async function action({ context, request, params }: ActionFunctionArgs) {
* They have delete permissions but shouldnt be able to delete other people's bookings
* Practically they should not be able to even view/access another booking but this is just an extra security measure
*/
const b = await getBooking({ id });
const b = await getBooking({ id, organizationId });
if (
b?.creatorId !== authSession.userId &&
b?.custodianUserId !== authSession.userId
Expand Down
7 changes: 4 additions & 3 deletions app/routes/_layout+/categories.$categoryId_.edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ const title = "Edit category";

export async function loader({ context, request, params }: LoaderFunctionArgs) {
const authSession = context.getSession();
await requirePermision({
const { organizationId } = await requirePermision({
userId: authSession.userId,
request,
entity: PermissionEntity.category,
action: PermissionAction.update,
});

const id = getRequiredParam(params, "categoryId");
const category = await getCategory({ id });
const category = await getCategory({ id, organizationId });

const colorFromServer = category?.color;

Expand All @@ -56,7 +56,7 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => [

export async function action({ context, request, params }: LoaderFunctionArgs) {
const authSession = context.getSession();
await requirePermision({
const { organizationId } = await requirePermision({
userId: authSession.userId,
request,
entity: PermissionEntity.category,
Expand All @@ -83,6 +83,7 @@ export async function action({ context, request, params }: LoaderFunctionArgs) {
const rsp = await updateCategory({
...result.data,
id,
organizationId,
});

// Handle response error when creating. Mostly due to duplicate name
Expand Down
2 changes: 1 addition & 1 deletion app/routes/_layout+/locations.$locationId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const loader = async ({
});

if (!location) {
throw new ShelfStackError({ message: "Not Found", status: 404 });
throw new ShelfStackError({ message: "Location not found", status: 404 });
}

const totalItems = totalAssetsWithinLocation;
Expand Down
5 changes: 4 additions & 1 deletion app/routes/_layout+/settings.workspace.$workspaceId.edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export async function loader({ context, request, params }: LoaderFunctionArgs) {
});
const id = getRequiredParam(params, "workspaceId");

const organization = await getOrganization({ id });
const organization = await getOrganization({
id,
userId: authSession.userId,
});
if (!organization) {
throw new Response("Not Found", { status: 404 });
}
Expand Down
15 changes: 12 additions & 3 deletions app/routes/_layout+/tags.$tagId_.edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { getRequiredParam, isFormProcessing } from "~/utils";
import { appendToMetaTitle } from "~/utils/append-to-meta-title";

import { sendNotification } from "~/utils/emitter/send-notification.server";
import { ShelfStackError } from "~/utils/error";
import { PermissionAction, PermissionEntity } from "~/utils/permissions";
import { requirePermision } from "~/utils/roles.server";
import { zodFieldIsRequired } from "~/utils/zod";
Expand All @@ -30,15 +31,22 @@ const title = "Edit Tag";

export async function loader({ context, request, params }: LoaderFunctionArgs) {
const authSession = context.getSession();
await requirePermision({
const { organizationId } = await requirePermision({
userId: authSession.userId,
request,
entity: PermissionEntity.tag,
action: PermissionAction.update,
});

const id = getRequiredParam(params, "tagId");
const tag = await getTag({ id });
const tag = await getTag({ id, organizationId });

if (!tag) {
throw new ShelfStackError({
status: 404,
message: "Tag not found",
});
}

const header = {
title,
Expand All @@ -53,7 +61,7 @@ export const meta: MetaFunction<typeof loader> = ({ data }) => [

export async function action({ context, request, params }: LoaderFunctionArgs) {
const authSession = context.getSession();
await requirePermision({
const { organizationId } = await requirePermision({
userId: authSession.userId,
request,
entity: PermissionEntity.tag,
Expand All @@ -80,6 +88,7 @@ export async function action({ context, request, params }: LoaderFunctionArgs) {
const rsp = await updateTag({
...result.data,
id,
organizationId,
});

if (rsp?.error) {
Expand Down

0 comments on commit 79a44e2

Please sign in to comment.