Skip to content

Commit

Permalink
Merge pull request #21 from coldsurfers/feature/migrate-billets-server
Browse files Browse the repository at this point in the history
Migrated billets server
  • Loading branch information
yungblud authored Jan 23, 2024
2 parents 22fa04b + 682d18e commit e915495
Show file tree
Hide file tree
Showing 23 changed files with 669 additions and 11 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
],
"nohoist": [
"**/billets-admin-server",
"**/billets-admin-server/**"
"**/billets-admin-server/**",
"**/billets-server",
"**/billets-server/**"
]
},
"scripts": {
"super-install": "yarn install --immutable --force || yarn install --immutable --force"
"super-install": "yarn install --immutable --force || yarn install --immutable --force",
"super-remove": "rm -rf ./packages/*/node_modules && rm -rf ./node_modules"
},
"devDependencies": {
"typescript": "^5.3.3"
Expand Down
4 changes: 4 additions & 0 deletions packages/billets-admin-client/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
4 changes: 4 additions & 0 deletions packages/billets-admin-server/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
46 changes: 46 additions & 0 deletions packages/billets-server/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": [
"airbnb-base",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"prettier"
],
"rules": {
"prettier/prettier": "error",
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
]
},
"ignorePatterns": [
"node_modules",
"build",
"dist",
"public",
"gql/resolvers-types.ts"
],
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".ts", ".jsx", ".tsx"]
}
}
}
}
6 changes: 6 additions & 0 deletions packages/billets-server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
.eslintcache
dist
.vercel
.env
src/prisma/schema.prisma
6 changes: 6 additions & 0 deletions packages/billets-server/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}
1 change: 1 addition & 0 deletions packages/billets-server/commitlint.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-conventional'] }
51 changes: 51 additions & 0 deletions packages/billets-server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@coldsurfers/billets-server",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@commitlint/cli": "^17.4.2",
"@commitlint/config-conventional": "^17.4.2",
"@types/crypto-js": "^4.1.1",
"@types/jsonwebtoken": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"eslint": "^7.32.0 || ^8.2.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-prettier": "^4.2.1",
"husky": "^8.0.3",
"lint-staged": "^13.1.0",
"prettier": "2.8.3",
"prisma": "^5.7.1",
"typescript": "^4.9.5"
},
"dependencies": {
"@prisma/client": "^5.8.0",
"@vercel/node": "^2.9.0",
"crypto-js": "^4.1.1",
"dotenv": "^16.0.3",
"fastify": "^4.12.0",
"jsonwebtoken": "^9.0.0",
"jwt-decode": "^3.1.2"
},
"scripts": {
"lint": "eslint --cache \"src/**/*.{js,jsx,ts,tsx}\" \"vercel/**/*.{js,jsx,ts,tsx}\"",
"lint:fix": "yarn lint --fix",
"prisma:copy": "cp -r ../../prisma/schema.prisma ./src/prisma/schema.prisma",
"postinstall": "yarn prisma:copy && yarn prisma:generate",
"debug": "vercel dev --listen 3001",
"deploy": "vercel",
"build": "tsc",
"vercel:sync-env": "vercel env pull",
"prisma:db-push": "yarn prisma db push --schema ./src/prisma/schema.prisma",
"prisma:generate": "yarn prisma generate --schema ./src/prisma/schema.prisma"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"yarn run lint:fix",
"bash -c 'yarn build --noEmit'"
]
}
}
27 changes: 27 additions & 0 deletions packages/billets-server/src/lib/encryptPassword.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import CryptoJS from 'crypto-js'

const encryptPassword = ({
plain,
originalSalt,
}: {
plain: string
originalSalt?: string
}) => {
const salt =
originalSalt ||
CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex)

const iterations = 10000

const key = CryptoJS.PBKDF2(plain, CryptoJS.enc.Hex.parse(salt), {
keySize: 512 / 32,
iterations,
})

return {
encrypted: key.toString(CryptoJS.enc.Base64),
salt,
}
}

export default encryptPassword
25 changes: 25 additions & 0 deletions packages/billets-server/src/lib/jwt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import jwt from 'jsonwebtoken'
import dotenv from 'dotenv'
import jwtDecode from 'jwt-decode'
import { FstvlLifeJwtPayload } from './types'

dotenv.config()

const { JWT_SECRET: secret } = process.env

/* eslint-disable import/prefer-default-export */
export function generateToken(payload: FstvlLifeJwtPayload) {
if (!secret) {
throw new Error('no secret')
}
return jwt.sign(payload, secret)
}

export function decodeToken(token: string) {
try {
const decoded = jwtDecode<FstvlLifeJwtPayload>(token)
return decoded
} catch (e) {
return null
}
}
5 changes: 5 additions & 0 deletions packages/billets-server/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { JwtPayload } from 'jwt-decode'

export interface FstvlLifeJwtPayload extends JwtPayload {
id: number
}
11 changes: 11 additions & 0 deletions packages/billets-server/src/prisma/connect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PrismaClient } from '@prisma/client'

export const prisma = new PrismaClient()

export async function connect() {
await prisma.$connect()
}

export async function disconnect() {
await prisma.$disconnect()
}
27 changes: 27 additions & 0 deletions packages/billets-server/src/routes/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FastifyPluginCallback } from 'fastify'
import { signinHandler, signupHandler } from './authHandlers'

const authRoute: FastifyPluginCallback = (fastify, opts, done) => {
fastify.post(
'/signin',
{
preHandler: async (req, rep, next) => {
if (!req.body) {
return rep.status(400).send({})
}
const { email, password } = req.body
if (!email || !password) {
return rep.status(400).send({})
}
return next()
},
},
signinHandler
)

fastify.post('/signup', signupHandler)

done()
}

export default authRoute
49 changes: 49 additions & 0 deletions packages/billets-server/src/routes/authHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { RouteHandler } from 'fastify'
import encryptPassword from '../lib/encryptPassword'
import { generateToken } from '../lib/jwt'
import { prisma } from '../prisma/connect'

export const signinHandler: RouteHandler<{
Body: {
email: string
password: string
}
}> = async (req, rep) => {
const { email, password } = req.body

try {
const existing = await prisma.user.findUnique({
where: {
email,
},
})
if (!existing) {
return rep.status(404).send({})
}
const { encrypted } = encryptPassword({
plain: password,
originalSalt: existing.passwordSalt,
})
if (encrypted !== existing.password) {
return rep.status(401).send({})
}
const token = generateToken({
id: existing.id,
})
return {
user: {
id: existing.id,
email: existing.email,
createdAt: existing.createdAt.toISOString(),
},
token,
}
} catch (e) {
console.error(e)
return rep.status(500).send({})
}
}

export const signupHandler: RouteHandler<{
Body: { email: string; password: string; passwordConfirm: string }
}> = async () => {}
29 changes: 29 additions & 0 deletions packages/billets-server/src/routes/concert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { FastifyPluginCallback } from 'fastify'
import {
concertCategoryList,
concertHandler,
concertListHandler,
concertRecentListHandler,
concertSearchHandler,
} from './concertHandlers'

const concertRoute: FastifyPluginCallback = (fastify, opts, done) => {
// concert list
fastify.get('/', concertListHandler)

// concert recent list
fastify.get('/recent', concertRecentListHandler)

// concert
fastify.get('/:id', concertHandler)

// concert category list
fastify.get('/category', concertCategoryList)

// concert search
fastify.get('/search', concertSearchHandler)

done()
}

export default concertRoute
Loading

0 comments on commit e915495

Please sign in to comment.