Skip to content

Commit

Permalink
Add useCrossDomainStorage hook and integrate it into authentication…
Browse files Browse the repository at this point in the history
… components

* **New Hook**: Create `useCrossDomainStorage` to handle cross-domain storage using `localStorage` and `postMessage`
  - Implement `set` function to store data in `localStorage` and notify other domains
  - Implement `get` function to retrieve data from `localStorage`
  - Implement `handlePostMessage` function to listen for `postMessage` events and update `localStorage`

* **AccountSwitcherModal**: Integrate `useCrossDomainStorage` hook
  - Import and use `get` and `set` functions
  - Update `fetchUser` function to use `get`
  - Update `handleBackdropClick` function to use `set`

* **SignInButton**: Integrate `useCrossDomainStorage` hook
  - Import and use `set` function
  - Update `onClick` function to use `set`

* **useOxySession**: Integrate `useCrossDomainStorage` hook
  - Import and use `get` and `set` functions
  - Update `fetchSessionData` function to use `get` and `set`
  • Loading branch information
NateIsern committed Nov 28, 2024
1 parent a88f9ba commit 89cea05
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/components/auth/AccountSwitcherModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AiOutlineClose } from "react-icons/ai";
import { Avatar } from "../../features/profile";

import getUserById from "../../hooks/getUserById";
import useCrossDomainStorage from "../../hooks/useCrossDomainStorage";

import styles from "./styles/account-switcher-modal.module.css";

Expand All @@ -34,13 +35,15 @@ export const AccountSwitcherModal = forwardRef<
>((props, ref) => {
const { onClose } = props;
const { session } = useOxySession();
const { get, set } = useCrossDomainStorage();
const [user, setUser] = useState<User | null>(null);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchUser = async () => {
try {
const fetchedUser = await getUserById(session?.user?.id);
const clientKey = get("clientKey");
const fetchedUser = await getUserById(clientKey);
setUser(fetchedUser);
} catch (error) {
if (error instanceof Error) {
Expand All @@ -54,13 +57,14 @@ export const AccountSwitcherModal = forwardRef<
if (session) {
fetchUser();
}
}, [session]);
}, [session, get]);

if (!session) return null;

const handleBackdropClick = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
if (e.currentTarget === e.target) {
set("clientKey", "");
onClose();
}
};
Expand Down
4 changes: 4 additions & 0 deletions src/components/auth/SignInButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import styles from "./styles/sign-in-button.module.css";
import { OxyLogo } from "../assets/oxy-logo";
import useCrossDomainStorage from "../../hooks/useCrossDomainStorage";

export const SignInButton = ({
icon = <OxyLogo />,
Expand All @@ -11,11 +12,14 @@ export const SignInButton = ({
text?: string;
callback?: string;
}) => {
const { set } = useCrossDomainStorage();

const onClick = () => {
if (typeof window !== "undefined") {
const redirectUrl = `https://auth.oxy.so/?callback=${encodeURIComponent(
callback
)}`;
set("clientKey", ""); // Clear the clientKey before redirecting
window.location.href = redirectUrl;
}
};
Expand Down
30 changes: 30 additions & 0 deletions src/hooks/useCrossDomainStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect } from "react";

const useCrossDomainStorage = () => {
const set = (key: string, value: string) => {
localStorage.setItem(key, value);
window.postMessage({ key, value }, "*");
};

const get = (key: string) => {
return localStorage.getItem(key);
};

const handlePostMessage = (event: MessageEvent) => {
if (event.origin !== window.location.origin) {
const { key, value } = event.data;
localStorage.setItem(key, value);
}
};

useEffect(() => {
window.addEventListener("message", handlePostMessage);
return () => {
window.removeEventListener("message", handlePostMessage);
};
}, []);

return { set, get };
};

export default useCrossDomainStorage;
7 changes: 5 additions & 2 deletions src/hooks/useOxySession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import localforage from "localforage";

import { OXY_AUTH_URL } from "../config";
import { UserRole } from "../types";
import useCrossDomainStorage from "./useCrossDomainStorage";

interface SessionModel {
user: {
Expand Down Expand Up @@ -49,10 +50,12 @@ export const useSessionStore = create<SessionState>((set) => {

// If the session ID was not found in the URL parameters, get it from local storage
if (!clientKey) {
clientKey = await localforage.getItem<string>("clientKey");
const { get } = useCrossDomainStorage();
clientKey = get("clientKey");
} else {
// If the session ID was found in the URL parameters, set it in local storage
await localforage.setItem<string>("clientKey", clientKey);
const { set } = useCrossDomainStorage();
set("clientKey", clientKey);
}

const response = await axios.get(
Expand Down

0 comments on commit 89cea05

Please sign in to comment.