Skip to content

Instantly share code, notes, and snippets.

@joeelmahallawy
Last active May 2, 2023 02:58
Show Gist options
  • Save joeelmahallawy/9235206a468158b59b6ec43b54781bea to your computer and use it in GitHub Desktop.
Save joeelmahallawy/9235206a468158b59b6ec43b54781bea to your computer and use it in GitHub Desktop.
export const UserContext = React.createContext(null);
const IndexPage = () => {
const [session, setSession] = useState(null);
useEffect(() => {
(async () => {
const getUser = await fetch(`/api/session`, {
headers: { Authorization: `Bearer ${getCookie("jwt")}` },
});
const user = await getUser.json();
setSession(user);
})();
}, []);
return (
<UserContext.Provider value={[session, setSession]}>
<Box>
<HeaderMenu />
<Tabs defaultValue="chat" sx={{}}>
<Tabs.List sx={{ position: "sticky" }} grow>
<Tabs.Tab value="chat" icon={<IconMessageCircle size="1.1rem" />}>
<Text sx={{ fontSize: "1rem" }}>Chat</Text>
</Tabs.Tab>
<Tabs.Tab value="images" icon={<IconPhoto size="1.1rem" />}>
<Text sx={{ fontSize: "1rem" }}>Images</Text>
</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="chat" pt="xs">
<ChatPrompts />
</Tabs.Panel>
<Tabs.Panel value="images" pt="xs">
<ImagePrompts />
</Tabs.Panel>
</Tabs>
</Box>
</UserContext.Provider>
);
};
export default IndexPage;
// some CHILD COMPONENT of our IndexPage
const AnotherComponent = ()=>{
// use the session (user's state) anywhere with this line
const [session, setSession] = useContext(UserContext);
return <Box>hello</Box>
}
import { deleteCookie, getCookie, setCookie } from "cookies-next";
import grant from "grant";
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../../../prisma";
import { getEnvironmentWebsiteURL, stripe } from "../../../../utils";
import jsonwebtoken from "jsonwebtoken";
import { User } from "@prisma/client";
const config = {
defaults: {
origin: getEnvironmentWebsiteURL(),
prefix: "/api/oauth",
transport: "state",
response: ["tokens", "raw", "jwt", "profile"],
},
google: {
key: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
secret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET,
scope: [
"openid",
"email",
// personal info access
"https://www.googleapis.com/auth/userinfo.profile",
],
nonce: true,
prompt: "consent",
custom_params: { access_type: "offline" },
callback: `${getEnvironmentWebsiteURL()}/api/oauth/google/callback`,
},
};
// session configs
const grantInstance = grant.vercel({
config: config,
session: { secret: "grant" },
});
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
try {
// get session on callback
const response = await grantInstance(req, res);
const {
profile: { email, name, picture: profilePicture },
} = response.response as {
profile: {
name: string;
picture: string;
email: string;
};
};
// find user, or create if they don't exist
let user: User;
user = await prisma.user.findUnique({ where: { email } });
if (!user) {
const customer = await stripe.customers.create({
email,
name,
});
user = await prisma.user.create({
data: { email, name, profilePicture, stripeCustomerId: customer.id },
});
}
// sign jwt with user's email
const jwt = jsonwebtoken.sign(
{ email: user.email },
process.env.NEXT_PUBLIC_JWT_SECRET_KEY,
{ expiresIn: "24h" }
);
// set jwt in cookie
setCookie("jwt", jwt, { req, res, maxAge: 60 * 60 * 24 });
return res.redirect(`/app`);
} catch (err) {
return res.status(500).send({ error: err.message })
}
};
export default handler;
import { setCookie, setCookies } from "cookies-next";
import grant from "grant";
import { NextApiRequest, NextApiResponse } from "next";
import { getEnvironmentWebsiteURL } from "../../../../utils";
// configs for creating oauth session with google
const config = {
defaults: {
origin: getEnvironmentWebsiteURL(),
prefix: "/api/oauth",
transport: "state",
response: ["tokens", "raw", "jwt", "profile"],
},
google: {
key: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
secret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET,
scope: [
"openid",
"email",
// personal info access
"https://www.googleapis.com/auth/userinfo.profile",
],
nonce: true,
prompt: "consent",
custom_params: { access_type: "offline" },
callback: `${getEnvironmentWebsiteURL()}/api/oauth/google/callback`,
},
};
const grantInstance = grant.vercel({
config: config,
session: { secret: "grant" },
});
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
// run it when we enter url `<WEBSITE_URL>/api/oauth/google`
await grantInstance(req, res);
};
export default handler;
import jsonwebtoken from "jsonwebtoken";
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../prisma";
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (!req.headers.authorization)
return res.status(401).json({ error: `Unauthenticated` });
const jwt = req.headers.authorization.replace("Bearer ", "");
const { email } = jsonwebtoken.verify(
jwt,
process.env.NEXT_PUBLIC_JWT_SECRET_KEY
);
const session = await prisma.user.findUnique({ where: { email } });
return res.status(200).json(session);
};
export default handler;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment