I'm trying to implement MongoDB, Next.JS and Passport.js, However upon starting my app and while trying to login, I get this 500 status error:
Cannot access 'getSession' before initialization
The preamble for all this is I am using a hook which calls/api/user to see if the req.user has been set by passport thus creating the 'user' below. And if one exists you get access to the other links/routes in the app.
This is the function declaration regarding the getSession function in the session.js file. So I suspect this is what is causing the circular dependencies issue, naturally.
import MongoStore from "connect-mongo";
import nextSession from 'next-session';
import { getMongoClient } from "./mongodb";
const mongoStore = MongoStore.create({
clientPromise: getMongoClient(),
stringify: false,
});
const getSession = nextSession({
store: mongoStore,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 2 * 7 * 24 * 60 * 60, // 2 weeks,
path: "/",
sameSite: "strict",
},
touchAfter: 1 * 7 * 24 * 60 * 60, // 1 week
});
export default function session(req, res, next) {
getSession(req, res);
next();
}
And this is the auth file with the passport file, passport initialization and session.
import passport from '../lib/passport'
import session from '../lib/session'
const auths = [session, passport.initialize(), passport.session()];
export default auths;
/component/Layout
export default function Layout({ children, showFooter = false }) {
const [user, { mutate }] = useCurrentUser();
async function handleLogout() {
axios
.get('/api/logout').then(() => {
mutate({ user: null })
Router.push('/',)
}).catch(err => console.log('err', err))
}
return <>
<div className="shadow bg-base-200 drawer h-screen">
<div className="flex-none hidden lg:block">
<ul className="menu horizontal">
{user
?
<>
<li>
<Link href="/profile">
<a>Profile</a>
</Link>
</li>
<li>
<Link href="/dashboard">
<a>Dashboard</a>
</Link>
</li>
<li>
<a role="button" onClick={handleLogout}>
Logout
</a>
</li>
<li className="avatar">
<div className="rounded-full w-10 h-10 m-1">
<img src="https://i.pravatar.cc/500?img=32" />
</div>
</li></>
:
<>
<li>
<Link href="/login">
<a>Login</a>
</Link>
</li>
<li>
<Link href="/registration">
<a>Register</a>
</Link>
</li>
</>
}
</ul>
</div>
</div>
</>;
}
This is the hook itself:
import useSWR from 'swr';
export const fetcher = (url) => {
try {
return fetch(url).then((res) => {
console.log('res', res)
return res.json()
})
} catch (error) {
console.log('error', error)
}
}
export function useCurrentUser() {
const { data, mutate } = useSWR('/api/user', fetcher);
const user = data?.user;
return [user, { mutate }];
}
export function useUser(id) {
const { data } = useSWR(`/api/users/${id}`, fetcher, {
revalidateOnFocus: false,
});
return data?.user;
}
And this is the api: /api/user:
import nextConnect from 'next-connect'
import auth from '/middleware/auth'
const handler = nextConnect()
handler
.use(auth)
.get((req, res) => {
console.log("req.user ", req.user);
if (req.user) {
res.json({ user: req.user })
} else {
res.json({ user: null })
}
})
export default handler
Also this is my repo And this is a link to the app on vercel.