2
0

Add user account page

This commit is contained in:
Baptiste Arnaud
2021-12-27 15:59:32 +01:00
parent 698867da5d
commit e10fe1a186
33 changed files with 911 additions and 129 deletions

View File

@ -1,4 +1,4 @@
import NextAuth from 'next-auth'
import NextAuth, { NextAuthOptions } from 'next-auth'
import { PrismaAdapter } from '@next-auth/prisma-adapter'
import EmailProvider from 'next-auth/providers/email'
import GitHubProvider from 'next-auth/providers/github'
@ -8,6 +8,7 @@ import CredentialsProvider from 'next-auth/providers/credentials'
import prisma from 'libs/prisma'
import { Provider } from 'next-auth/providers'
import { User } from 'db'
import { NextApiRequest, NextApiResponse } from 'next'
const providers: Provider[] = [
EmailProvider({
@ -67,7 +68,7 @@ if (process.env.NODE_ENV !== 'production')
})
)
export default NextAuth({
const createOptions = (req: NextApiRequest): NextAuthOptions => ({
adapter: PrismaAdapter(prisma),
secret: process.env.SECRET,
providers,
@ -75,13 +76,25 @@ export default NextAuth({
strategy: process.env.NODE_ENV === 'production' ? 'database' : 'jwt',
},
callbacks: {
jwt: async ({ token, user }) => {
user && (token.user = user)
jwt: async ({ token, user, account }) => {
if (req.url === '/api/auth/session?update' && token.user) {
token.user = await prisma.user.findUnique({
where: { id: (token.user as User).id },
})
} else if (user) {
token.user = user
}
account?.type && (token.providerType = account?.type)
return token
},
session: async ({ session, token, user }) => {
token?.user ? (session.user = token.user as User) : (session.user = user)
return session
return { ...session, providerType: token.providerType }
},
},
})
const handler = (req: NextApiRequest, res: NextApiResponse) => {
NextAuth(req, res, createOptions(req))
}
export default handler

View File

@ -0,0 +1,46 @@
import aws from 'aws-sdk'
import { NextApiRequest, NextApiResponse } from 'next'
import { getSession } from 'next-auth/react'
import { methodNotAllowed } from 'services/api/utils'
const maxUploadFileSize = 10485760 // 10 MB
const handler = async (
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
try {
res.setHeader('Access-Control-Allow-Origin', '*')
if (req.method === 'GET') {
const session = await getSession({ req })
if (!session) {
res.status(401)
return
}
aws.config.update({
accessKeyId: process.env.S3_UPLOAD_KEY,
secretAccessKey: process.env.S3_UPLOAD_SECRET,
region: process.env.S3_UPLOAD_REGION,
signatureVersion: 'v4',
})
const s3 = new aws.S3()
const post = s3.createPresignedPost({
Bucket: process.env.S3_UPLOAD_BUCKET,
Fields: {
ACL: 'public-read',
key: req.query.key,
'Content-Type': req.query.fileType,
},
Expires: 120, // seconds
Conditions: [['content-length-range', 0, maxUploadFileSize]],
})
return res.status(200).json(post)
}
return methodNotAllowed(res)
} catch (err) {
console.log(err)
}
}
export default handler

View File

@ -0,0 +1,35 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { methodNotAllowed } from 'services/api/utils'
import Stripe from 'stripe'
const usdPriceIdTest = 'price_1Jc4TQKexUFvKTWyGvsH4Ff5'
const createCheckoutSession = async (
req: NextApiRequest,
res: NextApiResponse
) => {
if (req.method === 'POST') {
if (!process.env.STRIPE_SECRET_KEY)
throw Error('STRIPE_SECRET_KEY var is missing')
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27',
})
const { email } = req.body
const session = await stripe.checkout.sessions.create({
success_url: `${req.headers.origin}/typebots?stripe=success`,
cancel_url: `${req.headers.origin}/typebots?stripe=cancel`,
automatic_tax: { enabled: true },
allow_promotion_codes: true,
customer_email: email,
line_items: [
{
price: usdPriceIdTest,
quantity: 1,
},
],
})
res.status(201).json(session)
}
return methodNotAllowed(res)
}
export default createCheckoutSession

View File

@ -0,0 +1,73 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { methodNotAllowed } from 'services/api/utils'
import Stripe from 'stripe'
import Cors from 'micro-cors'
import { buffer } from 'micro'
import prisma from 'libs/prisma'
import { Plan } from 'db'
if (!process.env.STRIPE_SECRET_KEY || !process.env.STRIPE_WEBHOOK_SECRET)
throw new Error('STRIPE_SECRET_KEY or STRIPE_WEBHOOK_SECRET missing')
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27',
})
const cors = Cors({
allowMethods: ['POST', 'HEAD'],
})
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET as string
export const config = {
api: {
bodyParser: false,
},
}
const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const buf = await buffer(req)
const sig = req.headers['stripe-signature']
if (!sig) return res.status(400).send(`stripe-signature is missing`)
try {
const event = stripe.webhooks.constructEvent(
buf.toString(),
sig.toString(),
webhookSecret
)
switch (event.type) {
case 'checkout.session.completed': {
const session = event.data.object as Stripe.Checkout.Session
const { customer_email } = session
if (!customer_email)
return res.status(500).send(`customer_email not found`)
await prisma.user.update({
where: { email: customer_email },
data: { plan: Plan.PRO, stripeId: session.customer as string },
})
}
case 'customer.subscription.deleted': {
const subscription = event.data.object as Stripe.Subscription
await prisma.user.update({
where: {
stripeId: subscription.customer as string,
},
data: {
plan: Plan.FREE,
},
})
}
}
} catch (err) {
if (err instanceof Error) {
console.error(err)
return res.status(400).send(`Webhook Error: ${err.message}`)
}
}
}
return methodNotAllowed(res)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default cors(webhookHandler as any)

View File

@ -0,0 +1,24 @@
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
import { getSession } from 'next-auth/react'
import { methodNotAllowed } from 'services/api/utils'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const session = await getSession({ req })
if (!session?.user)
return res.status(401).json({ message: 'Not authenticated' })
const id = req.query.id.toString()
if (req.method === 'PUT') {
const data = JSON.parse(req.body)
const typebots = await prisma.user.update({
where: { id },
data,
})
return res.send({ typebots })
}
return methodNotAllowed(res)
}
export default handler