Last active
May 2, 2023 02:58
-
-
Save joeelmahallawy/9235206a468158b59b6ec43b54781bea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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