Skip to content

Commit

Permalink
Merge pull request #568 from nttcom/topic/delete-cookie-and-use-getId…
Browse files Browse the repository at this point in the history
…Token

topic/delete cookie and use getIdToken
  • Loading branch information
mshim03 authored Jan 30, 2025
2 parents 53f944a + a684189 commit 6094b07
Show file tree
Hide file tree
Showing 30 changed files with 418 additions and 1,089 deletions.
1,245 changes: 296 additions & 949 deletions web/package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"notistack": "^3.0.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-cookie": "^7.2.1",
"react-dom": "^18.2.0",
"react-error-boundary": "^5.0.0",
"react-icons": "^5.0.1",
Expand Down
5 changes: 3 additions & 2 deletions web/src/components/PTeamLabel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Box, IconButton, Typography } from "@mui/material";
import PropTypes from "prop-types";
import React, { useState } from "react";

import { useSkipUntilAuthTokenIsReady } from "../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../hooks/auth";
import { useGetUserMeQuery } from "../services/tcApi";
import { APIError } from "../utils/APIError";
import { errorToString } from "../utils/func";
Expand All @@ -16,7 +16,8 @@ export function PTeamLabel(props) {

const [pteamSettingsModalOpen, setPTeamSettingsModalOpen] = useState(false);

const skip = useSkipUntilAuthTokenIsReady();
const skip = useSkipUntilAuthUserIsReady();

const {
data: userMe,
error: userMeError,
Expand Down
4 changes: 2 additions & 2 deletions web/src/components/PTeamSettingsModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import React, { useState } from "react";

import { TabPanel } from "../components/TabPanel";
import dialogStyle from "../cssModule/dialog.module.css";
import { useSkipUntilAuthTokenIsReady } from "../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../hooks/auth";
import { useGetPTeamQuery } from "../services/tcApi";
import { APIError } from "../utils/APIError";
import { a11yProps, errorToString } from "../utils/func.js";
Expand All @@ -27,7 +27,7 @@ export function PTeamSettingsModal(props) {
const { pteamId, onSetShow, show, defaultTabIndex } = props;
const [tab, setTab] = useState(defaultTabIndex ?? 0);

const skip = useSkipUntilAuthTokenIsReady() || !pteamId;
const skip = useSkipUntilAuthUserIsReady() || !pteamId;

const {
data: pteam,
Expand Down
6 changes: 2 additions & 4 deletions web/src/hooks/auth.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { useSelector } from "react-redux";

export function useSkipUntilAuthTokenIsReady() {
const authToken = useSelector((state) => state.auth.token);
const skip = authToken === undefined;
return skip;
export function useSkipUntilAuthUserIsReady() {
return !useSelector((state) => state.auth.authUserIsReady);
}
79 changes: 38 additions & 41 deletions web/src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { CssBaseline } from "@mui/material";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { SnackbarProvider } from "notistack";
import React from "react";
import { CookiesProvider } from "react-cookie";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { BrowserRouter as Router, Navigate, Route, Routes } from "react-router-dom";
Expand All @@ -28,46 +27,44 @@ const root = createRoot(container);

root.render(
<React.StrictMode>
<CookiesProvider>
<Provider store={store}>
<ThemeProvider theme={createTheme()}>
<CssBaseline />
<SnackbarProvider
maxSnack={3}
preventDuplicate={true}
anchorOrigin={{ horizontal: "center", vertical: "top" }}
autoHideDuration={5000}
>
<Router basename={import.meta.env.VITE_PUBLIC_URL}>
<Routes>
<Route exact path="/login" element={<Login />} />
<Route path="/reset_password" element={<ResetPassword />} />
<Route path="/sign_up" element={<SignUp />} />
<Route path="/email_verification" element={<EmailVerification />} />
<Route path="/" element={<App />}>
<Route index element={<Status />} />
<Route path="account">
<Route index element={<Account />} />
</Route>
<Route path="pteam">
<Route index element={<PTeam />} />
<Route path="join" element={<AcceptPTeamInvitation />} />
</Route>
<Route path="tags">
<Route index element={<Navigate to="/" />} />
<Route path=":tagId" element={<Tag />} />
</Route>
<Route path="*" element={<Navigate to="/" />} />
<Route path="topics">
<Route index element={<TopicManagement />} />
<Route path=":topicId" element={<TopicDetail />} />
</Route>
<Provider store={store}>
<ThemeProvider theme={createTheme()}>
<CssBaseline />
<SnackbarProvider
maxSnack={3}
preventDuplicate={true}
anchorOrigin={{ horizontal: "center", vertical: "top" }}
autoHideDuration={5000}
>
<Router basename={import.meta.env.VITE_PUBLIC_URL}>
<Routes>
<Route exact path="/login" element={<Login />} />
<Route path="/reset_password" element={<ResetPassword />} />
<Route path="/sign_up" element={<SignUp />} />
<Route path="/email_verification" element={<EmailVerification />} />
<Route path="/" element={<App />}>
<Route index element={<Status />} />
<Route path="account">
<Route index element={<Account />} />
</Route>
</Routes>
</Router>
</SnackbarProvider>
</ThemeProvider>
</Provider>
</CookiesProvider>
<Route path="pteam">
<Route index element={<PTeam />} />
<Route path="join" element={<AcceptPTeamInvitation />} />
</Route>
<Route path="tags">
<Route index element={<Navigate to="/" />} />
<Route path=":tagId" element={<Tag />} />
</Route>
<Route path="*" element={<Navigate to="/" />} />
<Route path="topics">
<Route index element={<TopicManagement />} />
<Route path=":topicId" element={<TopicDetail />} />
</Route>
</Route>
</Routes>
</Router>
</SnackbarProvider>
</ThemeProvider>
</Provider>
</React.StrictMode>,
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useSnackbar } from "notistack";
import React from "react";
import { useLocation, useNavigate } from "react-router-dom";

import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../../hooks/auth";
import { useApplyPTeamInvitationMutation, useGetPTeamInvitationQuery } from "../../services/tcApi";
import { APIError } from "../../utils/APIError";
import { commonButtonStyle } from "../../utils/const";
Expand All @@ -19,7 +19,7 @@ export function AcceptPTeamInvitation() {
const params = new URLSearchParams(useLocation().search);
const tokenId = params.get("token");

const skip = useSkipUntilAuthTokenIsReady();
const skip = useSkipUntilAuthUserIsReady();
const {
data: detail,
error: detailError,
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/Account/AccountPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useSnackbar } from "notistack";
import React, { useState } from "react";

import { UUIDTypography } from "../../components/UUIDTypography";
import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../../hooks/auth";
import { useGetUserMeQuery, useUpdateUserMutation } from "../../services/tcApi";
import { APIError } from "../../utils/APIError";
import { errorToString } from "../../utils/func";
Expand All @@ -28,7 +28,7 @@ export function Account() {
const { enqueueSnackbar } = useSnackbar();

const [updateUser] = useUpdateUserMutation();
const skip = useSkipUntilAuthTokenIsReady();
const skip = useSkipUntilAuthUserIsReady();
const {
data: userMe,
error: userMeError,
Expand Down
16 changes: 13 additions & 3 deletions web/src/pages/App/AppBar.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Menu as MenuIcon } from "@mui/icons-material";
import { AppBar as MuiAppBar, Box, Button, Divider, IconButton, Toolbar } from "@mui/material";
import { styled } from "@mui/material/styles";
import { signOut } from "firebase/auth";
import React from "react";
import { ErrorBoundary } from "react-error-boundary";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";

import { firebaseApi } from "../../services/firebaseApi";
import { tcApi } from "../../services/tcApi";
import { setAuthUserIsReady } from "../../slices/auth";
import { setDrawerOpen } from "../../slices/system";
import Firebase from "../../utils/Firebase";
import { drawerWidth } from "../../utils/const";

import { AppFallback } from "./AppFallback";
Expand Down Expand Up @@ -46,9 +49,16 @@ export function AppBar() {
const handleLogout = () => {
dispatch(firebaseApi.util.resetApiState()); // reset RTKQ
dispatch(tcApi.util.resetApiState()); // reset RTKQ
navigate("/login", {
state: { message: "Logged out successfully.", from: null, search: null },
});
dispatch(setAuthUserIsReady(false));
signOut(Firebase.getAuth())
.then(() => {
navigate("/login", {
state: { message: "Logged out successfully.", from: null, search: null },
});
})
.catch((error) => {
console.error(error);
});
};

return (
Expand Down
34 changes: 12 additions & 22 deletions web/src/pages/App/AppPage.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Box } from "@mui/material";
import { onAuthStateChanged, signOut } from "firebase/auth";
import React, { useEffect } from "react";
import { useCookies } from "react-cookie";
import { ErrorBoundary } from "react-error-boundary";
import { useDispatch, useSelector } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";

import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useTryLoginMutation } from "../../services/tcApi";
import { setAuthToken } from "../../slices/auth";
import { authCookieName, mainMaxWidth } from "../../utils/const";
import { setAuthUserIsReady } from "../../slices/auth";
import Firebase from "../../utils/Firebase";
import { mainMaxWidth } from "../../utils/const";

import { AppBar } from "./AppBar";
import { AppFallback } from "./AppFallback";
Expand All @@ -17,37 +16,28 @@ import { Main } from "./Main";
import { OutletWithCheckedParams } from "./OutletWithCheckedParams";

export function App() {
const [cookies, _setCookie, _removeCookie] = useCookies([authCookieName]);

const skip = useSkipUntilAuthTokenIsReady();

const dispatch = useDispatch();
const system = useSelector((state) => state.system);
const location = useLocation();
const navigate = useNavigate();

const [tryLogin] = useTryLoginMutation();
const dispatch = useDispatch();

useEffect(() => {
if (!skip) return; // auth token is ready
const _checkToken = async () => {
try {
const accessToken = cookies[authCookieName];
if (!accessToken) throw new Error("Missing cookie");
dispatch(setAuthToken(accessToken));
await tryLogin().unwrap(); // throw error if accessToken is expired
} catch (error) {
onAuthStateChanged(Firebase.getAuth(), (user) => {
if (!user) {
dispatch(setAuthUserIsReady(false));
navigate("/login", {
state: {
from: location.pathname,
search: location.search,
message: "Please login to continue.",
},
});
} else {
dispatch(setAuthUserIsReady(true));
}
};
_checkToken();
}, [cookies, dispatch, location, navigate, skip, tryLogin]);
});
}, [location, dispatch, navigate]);

return (
<>
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/App/OutletWithCheckedParams.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import { Outlet, useLocation, useNavigate } from "react-router-dom";

import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../../hooks/auth";
import { useGetUserMeQuery } from "../../services/tcApi";
import { APIError } from "../../utils/APIError";
import { errorToString } from "../../utils/func";
Expand All @@ -11,7 +11,7 @@ export function OutletWithCheckedParams() {
const navigate = useNavigate();
const location = useLocation();

const skip = useSkipUntilAuthTokenIsReady();
const skip = useSkipUntilAuthUserIsReady();

const {
data: userMe,
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/App/TeamSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { grey } from "@mui/material/colors";
import React, { useEffect, useMemo, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";

import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../../hooks/auth";
import { useGetUserMeQuery } from "../../services/tcApi";
import { APIError } from "../../utils/APIError";
import { LocationReader } from "../../utils/LocationReader";
Expand Down Expand Up @@ -35,7 +35,7 @@ export function TeamSelector() {
const [openPTeamCreationModal, setOpenPTeamCreationModal] = useState(false);
const locationReader = useMemo(() => new LocationReader(location), [location]);

const skip = useSkipUntilAuthTokenIsReady();
const skip = useSkipUntilAuthUserIsReady();
const {
data: userMe,
error: userMeError,
Expand Down
15 changes: 5 additions & 10 deletions web/src/pages/Login/LoginPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
TextField,
Typography,
} from "@mui/material";
import { signOut } from "firebase/auth";
import React, { useEffect, useState } from "react";
import { useCookies } from "react-cookie";
import { useDispatch } from "react-redux";
import { useLocation, useNavigate } from "react-router-dom";

Expand All @@ -25,9 +25,8 @@ import {
useSignInWithSamlPopupMutation,
} from "../../services/firebaseApi";
import { useCreateUserMutation, useTryLoginMutation } from "../../services/tcApi";
import { clearAuth } from "../../slices/auth";
import { setAuthUserIsReady } from "../../slices/auth";
import Firebase from "../../utils/Firebase";
import { authCookieName, cookiesOptions } from "../../utils/const";

export function Login() {
const [message, setMessage] = useState(null);
Expand All @@ -37,19 +36,17 @@ export function Login() {
const location = useLocation();
const navigate = useNavigate();

const [_cookies, setCookie, removeCookie] = useCookies([authCookieName]);

const [sendEmailVerification] = useSendEmailVerificationMutation();
const [signInWithEmailAndPassword] = useSignInWithEmailAndPasswordMutation();
const [signInWithSamlPopup] = useSignInWithSamlPopupMutation();
const [createUser] = useCreateUserMutation();
const [tryLogin] = useTryLoginMutation();

useEffect(() => {
dispatch(clearAuth());
removeCookie(authCookieName, cookiesOptions);
dispatch(setAuthUserIsReady(false));
setMessage(location.state?.message);
}, [dispatch, location, removeCookie]);
signOut(Firebase.getAuth());
}, [dispatch, location]);

const callSignInWithEmailAndPassword = async (email, password) => {
return await signInWithEmailAndPassword({ email, password })
Expand Down Expand Up @@ -79,8 +76,6 @@ export function Login() {
};

const navigateInternalPage = async (userCredential) => {
const accessToken = userCredential.user.accessToken;
setCookie(authCookieName, accessToken, cookiesOptions);
try {
await tryLogin().unwrap();
navigate({
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/PTeam/PTeamMemberMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Button, Dialog, DialogContent, Menu, MenuItem } from "@mui/material";
import PropTypes from "prop-types";
import React, { useState } from "react";

import { useSkipUntilAuthTokenIsReady } from "../../hooks/auth";
import { useSkipUntilAuthUserIsReady } from "../../hooks/auth";
import { useGetPTeamQuery, useGetUserMeQuery } from "../../services/tcApi";
import { APIError } from "../../utils/APIError";
import { errorToString, checkAdmin } from "../../utils/func";
Expand All @@ -23,7 +23,7 @@ export function PTeamMemberMenu(props) {
const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl);

const skip = useSkipUntilAuthTokenIsReady() || !pteamId;
const skip = useSkipUntilAuthUserIsReady() || !pteamId;
const {
data: userMe,
error: userMeError,
Expand Down
Loading

0 comments on commit 6094b07

Please sign in to comment.