[FEATURE] Initial Cairo Auth Integration
This commit is contained in:
parent
edbfc2348a
commit
184f1fa631
10 changed files with 234 additions and 14 deletions
|
@ -10,6 +10,7 @@ const defaultSettings = {
|
|||
simplifiedControls: false,
|
||||
logAppDetails: true,
|
||||
defaultPage: "home",
|
||||
cairoAuth: null,
|
||||
};
|
||||
|
||||
const settings = localSettings ? JSON.parse(localSettings) : defaultSettings;
|
||||
|
@ -27,6 +28,7 @@ const settingsUpdater = (oldState, settingsUpdate) => {
|
|||
if (settingsUpdate[k] === undefined) continue;
|
||||
settingsToUpdate[k] = settingsUpdate[k];
|
||||
}
|
||||
console.log("SAVING", settingsToUpdate);
|
||||
localStorage.setItem("settings", JSON.stringify(settingsToUpdate));
|
||||
};
|
||||
|
||||
|
|
|
@ -5,9 +5,13 @@ import Button from "@mui/material/Button";
|
|||
import SpeedDialIcon from "@mui/material/SpeedDialIcon";
|
||||
// Import Navbar
|
||||
/*import Navbar from "./Navbar.jsx";*/
|
||||
import { useCairoAuth } from "@mcl/util/auth.js";
|
||||
import MCLMenu from "./MCLMenu.jsx";
|
||||
import Auth from "@mcl/pages/Auth.jsx";
|
||||
|
||||
export default function Views() {
|
||||
const auth = useCairoAuth();
|
||||
if (!auth) return <Auth />;
|
||||
return (
|
||||
<div className="view">
|
||||
<MCLMenu />
|
||||
|
|
63
src/pages/Auth.jsx
Normal file
63
src/pages/Auth.jsx
Normal file
|
@ -0,0 +1,63 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { useSearchParams, useNavigate } from "react-router-dom";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
export default function Auth() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const currentServer = searchParams.get("token");
|
||||
|
||||
const nav = useNavigate();
|
||||
|
||||
const cairoLogin = () =>
|
||||
(window.location.href = `/api/auth/redirect?redirectUri=${window.location.href}`);
|
||||
|
||||
return (
|
||||
<Box
|
||||
className="auth"
|
||||
sx={{
|
||||
height: "100%",
|
||||
backgroundColor: (theme) => theme.palette.primary.main,
|
||||
}}
|
||||
>
|
||||
<Box className="auth-display" sx={{ display: "flex", height: "95vh" }}>
|
||||
<Box
|
||||
sx={{
|
||||
height: "50%",
|
||||
width: "50%",
|
||||
m: "auto",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
backgroundColor: "white",
|
||||
display: "inline-flex",
|
||||
m: "auto",
|
||||
borderRadius: "8px",
|
||||
height: "5rem",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
onClick={cairoLogin}
|
||||
sx={{ p: "1.5rem" }}
|
||||
endIcon={
|
||||
<img
|
||||
src="https://cairo.dunemask.net/cairo/icons/apple-touch-icon-120x120.png"
|
||||
width="48px"
|
||||
style={{ borderRadius: "4px" }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
Login with Cairo
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
56
src/util/auth.js
Normal file
56
src/util/auth.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { useState, useContext, useEffect } from "react";
|
||||
import { useSearchParams, useNavigate } from "react-router-dom";
|
||||
import SettingsContext from "@mcl/settings";
|
||||
|
||||
const verifyAuth = (authToken) =>
|
||||
fetch("/api/auth/verify", {
|
||||
headers: { Authorization: `Bearer ${authToken}` },
|
||||
})
|
||||
.then((res) => res.status === 200)
|
||||
.catch(() => false);
|
||||
|
||||
export function useCairoAuth() {
|
||||
const { state: settings, updateSettings } = useContext(SettingsContext);
|
||||
const [auth, setAuth] = useState(!!settings.cairoAuth);
|
||||
const [searchParams] = useSearchParams();
|
||||
const nav = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
const webToken = searchParams.get("cairoAuthToken");
|
||||
if (!webToken) return;
|
||||
verifyAuth(webToken).then(setAuth);
|
||||
updateSettings({ cairoAuth: webToken });
|
||||
nav("/");
|
||||
}, [searchParams]);
|
||||
|
||||
useEffect(() => {
|
||||
verifyAuth(settings.cairoAuth).then(setAuth);
|
||||
nav("/");
|
||||
}, [settings.cairoAuth]);
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
export function useAuth() {
|
||||
const { state: settings } = useContext(SettingsContext);
|
||||
const [auth, setAuth] = useState(!!!settings.cairoAuth);
|
||||
|
||||
if (!settings.cairoAuth) return auth;
|
||||
fetch("/api/auth/verify", {
|
||||
headers: { Authorization: `Bearer ${settings.cairoAuth}` },
|
||||
})
|
||||
.then(() => setAuth(true))
|
||||
.catch(() => setAuth(false));
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
export function useUpdateAuth() {
|
||||
const { updateSettings } = useContext(SettingsContext);
|
||||
const [searchParams] = useSearchParams();
|
||||
const webToken = searchParams.get("cairoAuthToken");
|
||||
if (webToken) {
|
||||
updateSettings({ cairoAuth: webToken });
|
||||
searchParams.delete("cairoAuthToken");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue