Skip to content

Commit

Permalink
🎉 add permission checker & minor fix
Browse files Browse the repository at this point in the history
  • Loading branch information
casperiv0 committed Oct 24, 2021
1 parent 4d408cc commit d1d57e8
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
36 changes: 34 additions & 2 deletions packages/client/src/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as React from "react";
import { useRouter } from "next/router";
import { getSessionUser } from "lib/auth";
import { cad as CAD, User } from "types/prisma";
import { cad as CAD, rank, User } from "types/prisma";
import { Loader } from "components/Loader";
import { useIsFeatureEnabled } from "lib/utils";
import { useListener } from "@casper124578/use-socket.io";
Expand All @@ -23,9 +23,19 @@ interface ProviderProps {
initialData: { session?: User | null };
}

const PERMISSIONS: Record<string, (user: User) => boolean> = {
"/dispatch": (user) => user.isDispatch,
"/leo": (user) => user.isLeo,
"/ems-fd": (user) => user.isEmsFd,
"/admin/manage/cad-settings": (user) => user.rank === "OWNER",
"/admin": (user) => user.rank !== rank.USER,
"/tow": (user) => user.isTow,
};

export const AuthProvider = ({ initialData, children }: ProviderProps) => {
const [user, setUser] = React.useState<User | null>(initialData.session ?? null);
const [cad, setCad] = React.useState<CAD | null>(null);
const [isForbidden, setForbidden] = React.useState(false);
const router = useRouter();

const isEnabled = useIsFeatureEnabled(cad ?? {});
Expand All @@ -46,6 +56,17 @@ export const AuthProvider = ({ initialData, children }: ProviderProps) => {
_setBodyTheme(user?.isDarkTheme ?? true);
}, [user?.isDarkTheme]);

React.useEffect(() => {
if (user) {
const p = hasPermissionForCurrentRoute(router.pathname, user);

if (!p) {
setForbidden(true);
router.push("/403");
}
}
}, [user, router]);

React.useEffect(() => {
handleGetUser();
}, [handleGetUser]);
Expand All @@ -72,7 +93,7 @@ export const AuthProvider = ({ initialData, children }: ProviderProps) => {

const value = { user, cad, setCad, setUser };

if (!router.pathname.includes("auth") && !user) {
if ((!router.pathname.includes("auth") && !user) || isForbidden) {
return (
<div id="unauthorized" className="fixed inset-0 grid place-items-center bg-transparent">
<span aria-label="loading...">
Expand Down Expand Up @@ -109,3 +130,14 @@ function _setBodyTheme(isDarkTheme: boolean) {
true;
// window.document.body.classList.add("dark");
}

function hasPermissionForCurrentRoute(path: string, user: User) {
const key = Object.keys(PERMISSIONS).find((v) => path.startsWith(v));
if (!key) return true;

const pathPermission = PERMISSIONS[key];

if (typeof pathPermission !== "function") return true;

return pathPermission(user);
}
2 changes: 1 addition & 1 deletion packages/client/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function requestAll(req: any, config: Config) {
req,
})
.then((v) => v.data)
.catch(() => ({ data: defaultValue }));
.catch(() => defaultValue);
}),
);
}
42 changes: 24 additions & 18 deletions packages/client/src/pages/citizen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { PersonFill } from "react-bootstrap-icons";
import { makeImageUrl } from "lib/utils";
import { ManageCallModal } from "components/citizen/tow/ManageTowCall";
import { Manage911CallModal } from "components/modals/Manage911CallModal";
import { useFeatureEnabled } from "hooks/useFeatureEnabled";

interface Props {
citizens: Citizen[];
Expand All @@ -26,6 +27,7 @@ export default function CitizenPage({ citizens }: Props) {
const t = useTranslations("Citizen");
const { openModal, closeModal } = useModal();
const [modal, setModal] = React.useState<string | null>(null);
const { TOW, TAXI } = useFeatureEnabled();

return (
<Layout>
Expand All @@ -50,24 +52,28 @@ export default function CitizenPage({ citizens }: Props) {
</ul>

<ul className="grid gap-2 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 mb-3">
<Button
onClick={() => {
setModal("tow");
openModal(ModalIds.ManageTowCall);
}}
className="text-left"
>
{t("createTowCall")}
</Button>
<Button
onClick={() => {
setModal("taxi");
openModal(ModalIds.ManageTowCall);
}}
className="text-left"
>
{t("createTaxiCall")}
</Button>
{TOW ? (
<Button
onClick={() => {
setModal("tow");
openModal(ModalIds.ManageTowCall);
}}
className="text-left"
>
{t("createTowCall")}
</Button>
) : null}
{TAXI ? (
<Button
onClick={() => {
setModal("taxi");
openModal(ModalIds.ManageTowCall);
}}
className="text-left"
>
{t("createTaxiCall")}
</Button>
) : null}
<Button onClick={() => openModal(ModalIds.Manage911Call)} className="text-left">
{t("create911Call")}
</Button>
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/pages/ems-fd/my-deputies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export default function MyDeputies({ deputies: data }: Props) {

export const getServerSideProps: GetServerSideProps = async ({ req, locale }) => {
const [{ deputies }, values] = await requestAll(req, [
["/leo", { officers: [] }],
["/ems-fd", { deputies: [] }],
["/admin/values/department?paths=division", []],
]);

Expand Down

0 comments on commit d1d57e8

Please sign in to comment.