Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: better-auth migration #291

Draft
wants to merge 1 commit into
base: staging
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"@adminjs/express": "^6.1.0",
"@adminjs/prisma": "^5.0.3",
"@adminjs/themes": "^1.0.1",
"@celluloid/auth": "workspace:*",
"@celluloid/prisma": "workspace:*",
"@celluloid/passport": "workspace:*",
"@celluloid/queue": "workspace:*",
"@celluloid/react-player": "2.14.0",
"@celluloid/trpc": "workspace:*",
Expand All @@ -48,6 +48,7 @@
"@types/linkify-urls": "^3.1.1",
"@uidotdev/usehooks": "^2.4.1",
"adminjs": "^7.8.13",
"better-auth": "^1.0.3",
"change-case": "^4.1.2",
"cookie-parser": "^1.4.7",
"copy-to-clipboard": "^3.3.3",
Expand All @@ -56,7 +57,6 @@
"enzyme": "^3.3.0",
"express": "^4.21.1",
"express-formidable": "^1.2.0",
"express-session": "^1.18.1",
"file-saver": "^2.0.5",
"formik": "^2.2.9",
"get-urls": "^11.0.0",
Expand All @@ -69,8 +69,6 @@
"moment-duration-format": "^2.2.2",
"mui-image": "^1.0.7",
"notistack": "^3.0.1",
"passport": "^0.6.0",
"passport-local": "^1.0.0",
"query-string": "^6.1.0",
"ramda": "^0.28.0",
"randomcolor": "^0.5.3",
Expand Down Expand Up @@ -116,7 +114,6 @@
"@types/cors": "^2.8.13",
"@types/express": "^4",
"@types/express-formidable": "^1",
"@types/express-session": "^1",
"@types/file-saver": "^2.0.5",
"@types/get-urls": "^9.1.3",
"@types/i18next": "^13.0.0",
Expand Down
56 changes: 30 additions & 26 deletions apps/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "dayjs/locale/fr"; // import locale

import { CssBaseline, Dialog, ThemeProvider } from "@mui/material";
import { CssBaseline, ThemeProvider } from "@mui/material";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { createWSClient, httpBatchLink, splitLink, wsLink } from "@trpc/client";
Expand All @@ -16,7 +16,6 @@ import React, { Suspense, useCallback, useState } from "react";
import { initReactI18next } from "react-i18next";
import {
BrowserRouter,
createBrowserRouter,
Navigate,
Route,
Routes,
Expand Down Expand Up @@ -55,10 +54,6 @@ import { createTheme } from "./theme";

const API_URL = "/api/trpc";

const WS_URL = `${location.protocol === "https:" ? "wss" : "ws"}://${
location.host
}/trpc`;

dayjs.extend(relativeTime);
dayjs.extend(isLeapYear); // use plugin
dayjs.extend(duration);
Expand Down Expand Up @@ -166,28 +161,37 @@ const App = () => {
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
splitLink({
condition(op) {
// check for operation type
return op.type === "subscription";
httpBatchLink({
url: "/api/trpc",
fetch(url, options) {
return fetch(url, {
...options,
credentials: "include",
});
},
// when condition is true, use normal request
true: wsLink({
client: createWSClient({
url: WS_URL,
}),
}),
// when condition is false, use batching
false: httpBatchLink({
url: API_URL,
fetch(url, options) {
return fetch(url, {
...options,
credentials: "include",
});
},
}),
}),
// splitLink({
// condition(op) {
// // check for operation type
// return op.type === "subscription";
// },
// // when condition is true, use normal request
// true: wsLink({
// client: createWSClient({
// url: WS_URL,
// }),
// }),
// // when condition is false, use batching
// false: httpBatchLink({
// url: API_URL,
// fetch(url, options) {
// return fetch(url, {
// ...options,
// credentials: "include",
// });
// },
// }),
// }),
],
})
);
Expand Down
29 changes: 16 additions & 13 deletions apps/frontend/src/components/AppBarMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
import { AppBar, Box, BoxProps, Button, styled, Toolbar } from "@mui/material";
import * as React from "react";
import {
AppBar,
Box,
type BoxProps,
Button,
styled,
Toolbar,
} from "@mui/material";
import type * as React from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router";
import { useNavigate } from "react-router";

import { getButtonLink } from "~components/ButtonLink";
import { Footer } from "~components/Footer";
import { LogoWithLabel } from "~components/LogoWithLabel";
import { SigninMenu } from "~components/SigninMenu";
import { trpc } from "~utils/trpc";

import { LanguageMenu } from "./LanguageMenu";
import { useSession } from "~/lib/auth-client";

const Offset = styled("div")(({ theme }) => theme.mixins.toolbar);

export const AppBarMenu: React.FC<BoxProps> = ({ children }) => {
const { t } = useTranslation();
const navigate = useNavigate();
const { data, isError } = trpc.user.me.useQuery(
{},
{ retry: false, keepPreviousData: false, cacheTime: 0 }
);

const location = useLocation();
const { data: session } = useSession();

const handleCreate = () => {
if (data) {
navigate(`/create`);
if (session) {
navigate("/create");
} else {
navigate("/signup", { state: { backgroundLocation: "/" } });
}
};

const handleJoin = () => {
if (!data) {
if (!session) {
navigate("/signup-student", { state: { backgroundLocation: "/" } });
} else {
navigate("/join", { state: { backgroundLocation: "/" } });
Expand Down Expand Up @@ -95,7 +98,7 @@ export const AppBarMenu: React.FC<BoxProps> = ({ children }) => {
{t("menu.about")}
</Button>

<SigninMenu user={!isError ? data : null} />
<SigninMenu user={session ? session.user : null} />
<LanguageMenu />
</Toolbar>
</AppBar>
Expand Down
2 changes: 1 addition & 1 deletion apps/frontend/src/components/SharedLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from "react";
import type * as React from "react";
import { Outlet } from "react-router-dom";

import { AppBarMenu } from "./AppBarMenu";
Expand Down
16 changes: 5 additions & 11 deletions apps/frontend/src/components/SigninMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import * as React from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router";

import { trpc, UserMe } from "~utils/trpc";

import { Avatar } from "./Avatar";
import { signOut, type User } from "~/lib/auth-client";

export const SigninMenu = ({ user }: { user: UserMe }) => {
export const SigninMenu = ({ user }: { user: User }) => {
const navigate = useNavigate();
const location = useLocation();

Expand All @@ -17,9 +16,6 @@ export const SigninMenu = ({ user }: { user: UserMe }) => {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);

const utils = trpc.useContext();
const mutation = trpc.user.logout.useMutation();

const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
Expand All @@ -28,9 +24,7 @@ export const SigninMenu = ({ user }: { user: UserMe }) => {
};

const handleLogout = async () => {
await mutation.mutateAsync();
utils.user.me.invalidate();
utils.project.list.invalidate();
await signOut();
handleClose();
navigate("/", { replace: true });
};
Expand Down Expand Up @@ -69,7 +63,7 @@ export const SigninMenu = ({ user }: { user: UserMe }) => {
borderColor: user.color,
borderStyle: "solid",
}}
src={user.avatar?.publicUrl}
src={user.image ?? undefined}
>
{user.initial}
</Avatar>
Expand Down Expand Up @@ -136,7 +130,7 @@ export const SigninMenu = ({ user }: { user: UserMe }) => {
},
}}
>
{user && user.role == "Admin" ? (
{user && user.role === "admin" ? (
<MenuItem onClick={handleOpenAdmin} data-testid="header-admin-button">
{t("menu.admin")}
</MenuItem>
Expand Down
32 changes: 16 additions & 16 deletions apps/frontend/src/components/auth/SignupDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
import { LoadingButton } from "@mui/lab";
import {
Alert,
Box,
Button,
DialogActions,
DialogContent,
Stack,
} from "@mui/material";
import { DialogActions, DialogContent } from "@mui/material";
import TextField from "@mui/material/TextField";
import { useFormik } from "formik";
import { Trans, useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router";
import { useNavigate } from "react-router";
import * as Yup from "yup";
import { signUp } from "~/lib/auth-client";

import { StyledDialog } from "~components/Dialog";
import { isTRPCClientError, trpc } from "~utils/trpc";

export const SignupDialog: React.FC = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const location = useLocation();

const utils = trpc.useContext();
const mutation = trpc.user.register.useMutation();
Expand Down Expand Up @@ -48,16 +41,23 @@ export const SignupDialog: React.FC = () => {
validateOnChange: true,
onSubmit: async (values) => {
try {
await mutation.mutateAsync({
username: values.username,
// await mutation.mutateAsync({
// username: values.username,
// email: values.email,
// password: values.password,
// });

const res = await signUp.email({
name: values.username,
email: values.email,
password: values.password,
});
console.log(res);

utils.user.me.invalidate();
navigate(`/confirm?email=${values.email}`, {
state: { backgroundLocation: "/" },
});
// utils.user.me.invalidate();
// navigate(`/confirm?email=${values.email}`, {
// state: { backgroundLocation: "/" },
// });
formik.setStatus("submited");
} catch (e) {
if (isTRPCClientError(e)) {
Expand Down
15 changes: 15 additions & 0 deletions apps/frontend/src/lib/auth-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createAuthClient } from "better-auth/react";
import {
emailOTPClient,
inferAdditionalFields,
} from "better-auth/client/plugins";
import type { auth } from "@celluloid/auth";

export const authClient = createAuthClient({
plugins: [emailOTPClient(), inferAdditionalFields<typeof auth>()],
});

export type Session = typeof authClient.$Infer.Session;
export type User = typeof authClient.$Infer.Session.user;

export const { signIn, signUp, signOut, useSession } = authClient;
6 changes: 2 additions & 4 deletions apps/frontend/src/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ export const HomePage: React.FC = () => {
{ retry: false, keepPreviousData: false, cacheTime: 0 }
);

const location = useLocation();

const { t } = useTranslation();
const navigate = useNavigate();

Expand All @@ -43,7 +41,7 @@ export const HomePage: React.FC = () => {
}, [isError, navigate]);

const handleCreate = () => {
navigate(`/create`);
navigate("/create");
};

return (
Expand Down Expand Up @@ -94,7 +92,7 @@ export const HomePage: React.FC = () => {
gutterBottom={true}
fontFamily={"abril_fatfaceregular"}
>
<Trans i18nKey={"home.tutoriel.subtitle"}></Trans>
<Trans i18nKey={"home.tutoriel.subtitle"} />
</Typography>

<Typography variant="subtitle1" gutterBottom={true}>
Expand Down
Loading