Skip to content

Commit

Permalink
Add authorization HOC
Browse files Browse the repository at this point in the history
  • Loading branch information
lkostrowski committed Oct 4, 2022
1 parent 6a162b7 commit 5fe9a50
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@
"import": "./app-bridge/index.mjs",
"require": "./app-bridge/index.js"
},
"./util": {
"types": "./util/index.d.ts",
"import": "./util/index.mjs",
"require": "./util/index.js"
},
"./handlers/next": {
"types": "./handlers/next/index.d.ts",
"import": "./handlers/next/index.mjs",
Expand Down
57 changes: 57 additions & 0 deletions src/app-bridge/with-authorization.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { NextPage } from "next";
import * as React from "react";
import { PropsWithChildren, ReactNode } from "react";

import { isInIframe, useIsMounted } from "../util";
import { useDashboardToken } from "./use-dashboard-token";

function SimpleError({ children }: PropsWithChildren<{}>) {
return (
<div style={{ padding: 32, color: "red" }}>
<p>{children}</p>
</div>
);
}

type Props = {
unmounted?: ReactNode;
notIframe?: ReactNode;
noDashboardToken?: ReactNode;
dashboardTokenInvalid?: ReactNode;
};

export const withAuthorization =
({
dashboardTokenInvalid = <SimpleError>Dashboard token is invalid</SimpleError>,
noDashboardToken = <SimpleError>Dashboard token doesn&quot;t exist</SimpleError>,
notIframe = <SimpleError>The view can only be displayed inside iframe.</SimpleError>,
unmounted = <p>Loading</p>,
}: Props) =>
<BaseProps extends React.ComponentProps<NextPage>>(
BaseComponent: React.FunctionComponent<BaseProps>
) => {
function AuthorizedPage(props: BaseProps) {
const mounted = useIsMounted();
const { isTokenValid, hasAppToken } = useDashboardToken();

if (!mounted) {
return unmounted;
}

if (!isInIframe()) {
return notIframe;
}

if (!hasAppToken) {
return noDashboardToken;
}

if (!isTokenValid) {
return dashboardTokenInvalid;
}

return <BaseComponent {...props} />;
}

return AuthorizedPage;
};
2 changes: 2 additions & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./is-in-iframe";
export * from "./use-is-mounted";
11 changes: 11 additions & 0 deletions src/util/is-in-iframe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const isInIframe = () => {
if (!document || !window) {
throw new Error("isInIframe should be called only in browser");
}

try {
return document.location !== window.parent.location;
} catch (e) {
return false;
}
};
8 changes: 8 additions & 0 deletions src/util/use-is-mounted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useEffect, useState } from "react";

export const useIsMounted = (): boolean => {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);

return mounted;
};

0 comments on commit 5fe9a50

Please sign in to comment.