👷 Transpile components for better DX
This commit is contained in:
committed by
Baptiste Arnaud
parent
898367a33b
commit
c1dd4d403e
36
packages/utils/api/encryption.ts
Normal file
36
packages/utils/api/encryption.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { randomBytes, createCipheriv, createDecipheriv } from 'crypto'
|
||||
|
||||
const algorithm = 'aes-256-gcm'
|
||||
const secretKey = process.env.ENCRYPTION_SECRET
|
||||
|
||||
export const encrypt = (
|
||||
data: object
|
||||
): { encryptedData: string; iv: string } => {
|
||||
if (!secretKey) throw new Error(`ENCRYPTION_SECRET is not in environment`)
|
||||
const iv = randomBytes(16)
|
||||
const cipher = createCipheriv(algorithm, secretKey, iv)
|
||||
const dataString = JSON.stringify(data)
|
||||
const encryptedData =
|
||||
cipher.update(dataString, 'utf8', 'hex') + cipher.final('hex')
|
||||
const tag = cipher.getAuthTag()
|
||||
return {
|
||||
encryptedData,
|
||||
iv: iv.toString('hex') + '.' + tag.toString('hex'),
|
||||
}
|
||||
}
|
||||
|
||||
export const decrypt = (encryptedData: string, auth: string): object => {
|
||||
if (!secretKey) throw new Error(`ENCRYPTION_SECRET is not in environment`)
|
||||
const [iv, tag] = auth.split('.')
|
||||
const decipher = createDecipheriv(
|
||||
algorithm,
|
||||
secretKey,
|
||||
Buffer.from(iv, 'hex')
|
||||
)
|
||||
decipher.setAuthTag(Buffer.from(tag, 'hex'))
|
||||
return JSON.parse(
|
||||
(
|
||||
decipher.update(Buffer.from(encryptedData, 'hex')) + decipher.final('hex')
|
||||
).toString()
|
||||
)
|
||||
}
|
4
packages/utils/api/index.ts
Normal file
4
packages/utils/api/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './utils'
|
||||
export * from './storage'
|
||||
export * from './sendEmailNotification'
|
||||
export * from './encryption'
|
18
packages/utils/api/sendEmailNotification.ts
Normal file
18
packages/utils/api/sendEmailNotification.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { createTransport, SendMailOptions } from 'nodemailer'
|
||||
import { env } from '../utils'
|
||||
|
||||
export const sendEmailNotification = (props: Omit<SendMailOptions, 'from'>) => {
|
||||
const transporter = createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: Number(process.env.SMTP_PORT),
|
||||
auth: {
|
||||
user: process.env.SMTP_USERNAME,
|
||||
pass: process.env.SMTP_PASSWORD,
|
||||
},
|
||||
})
|
||||
|
||||
return transporter.sendMail({
|
||||
from: env('SMTP_FROM'),
|
||||
...props,
|
||||
})
|
||||
}
|
53
packages/utils/api/storage.ts
Normal file
53
packages/utils/api/storage.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { config, Endpoint, S3 } from 'aws-sdk'
|
||||
|
||||
type GeneratePresignedUrlProps = {
|
||||
filePath: string
|
||||
fileType?: string
|
||||
sizeLimit?: number
|
||||
}
|
||||
|
||||
const tenMB = 10 * 1024 * 1024
|
||||
const tenMinutes = 10 * 60
|
||||
|
||||
export const generatePresignedUrl = ({
|
||||
filePath,
|
||||
fileType,
|
||||
sizeLimit = tenMB,
|
||||
}: GeneratePresignedUrlProps): S3.PresignedPost => {
|
||||
if (
|
||||
!process.env.S3_ENDPOINT ||
|
||||
!process.env.S3_ACCESS_KEY ||
|
||||
!process.env.S3_SECRET_KEY
|
||||
)
|
||||
throw new Error(
|
||||
'S3 not properly configured. Missing one of those variables: S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY'
|
||||
)
|
||||
|
||||
const sslEnabled =
|
||||
process.env.S3_SSL && process.env.S3_SSL === 'false' ? false : true
|
||||
config.update({
|
||||
accessKeyId: process.env.S3_ACCESS_KEY,
|
||||
secretAccessKey: process.env.S3_SECRET_KEY,
|
||||
region: process.env.S3_REGION,
|
||||
sslEnabled,
|
||||
})
|
||||
const protocol = sslEnabled ? 'https' : 'http'
|
||||
const s3 = new S3({
|
||||
endpoint: new Endpoint(
|
||||
`${protocol}://${process.env.S3_ENDPOINT}${
|
||||
process.env.S3_PORT ? `:${process.env.S3_PORT}` : ''
|
||||
}`
|
||||
),
|
||||
})
|
||||
|
||||
const presignedUrl = s3.createPresignedPost({
|
||||
Bucket: process.env.S3_BUCKET ?? 'typebot',
|
||||
Fields: {
|
||||
key: filePath,
|
||||
'Content-Type': fileType,
|
||||
},
|
||||
Expires: tenMinutes,
|
||||
Conditions: [['content-length-range', 0, sizeLimit]],
|
||||
})
|
||||
return presignedUrl
|
||||
}
|
38
packages/utils/api/utils.ts
Normal file
38
packages/utils/api/utils.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export const methodNotAllowed = (
|
||||
res: NextApiResponse,
|
||||
customMessage?: string
|
||||
) => res.status(405).json({ message: customMessage ?? 'Method Not Allowed' })
|
||||
|
||||
export const notAuthenticated = (
|
||||
res: NextApiResponse,
|
||||
customMessage?: string
|
||||
) => res.status(401).json({ message: customMessage ?? 'Not authenticated' })
|
||||
|
||||
export const notFound = (res: NextApiResponse, customMessage?: string) =>
|
||||
res.status(404).json({ message: customMessage ?? 'Not found' })
|
||||
|
||||
export const badRequest = (res: NextApiResponse, customMessage?: any) =>
|
||||
res.status(400).json({ message: customMessage ?? 'Bad Request' })
|
||||
|
||||
export const forbidden = (res: NextApiResponse, customMessage?: string) =>
|
||||
res.status(403).json({ message: customMessage ?? 'Bad Request' })
|
||||
|
||||
export const initMiddleware =
|
||||
(
|
||||
handler: (
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
middleware: (result: any) => void
|
||||
) => void
|
||||
) =>
|
||||
(req: any, res: any) =>
|
||||
new Promise((resolve, reject) => {
|
||||
handler(req, res, (result) => {
|
||||
if (result instanceof Error) {
|
||||
return reject(result)
|
||||
}
|
||||
return resolve(result)
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user