hash clientSecret and better logging for sdk

This commit is contained in:
Carl-Gerhard Lindesvärd
2023-10-12 13:51:11 +02:00
parent 888d6db16b
commit 5e382911a8
7 changed files with 115 additions and 40 deletions

View File

@@ -14,9 +14,7 @@ app.use(morgan(':method :url :status :response-time ms'))
// Public routes
app.get('/', (req, res) => res.json('Welcome to Mixan'))
if (process.env.SETUP) {
app.use('/setup', setup)
}
app.use('/setup', setup)
// Protected routes
app.use(authMiddleware)

View File

@@ -1,27 +1,45 @@
import { NextFunction, Request, Response } from "express"
import { db } from "../db"
import { createError } from "../responses/errors"
import { NextFunction, Request, Response } from 'express'
import { db } from '../db'
import { HttpError, createError } from '../responses/errors'
import { verifyPassword } from '../services/hash'
export async function authMiddleware(req: Request, res: Response, next: NextFunction) {
const secret = req.headers['mixan-client-secret'] as string | undefined
if(!secret) {
return next(createError(401, 'Misisng client secret'))
}
const client = await db.client.findFirst({
where: {
secret,
},
})
if(!client) {
return next(createError(401, 'Invalid client secret'))
}
export async function authMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
try {
const clientId = req.headers['mixan-client-id'] as string | undefined
const clientSecret = req.headers['mixan-client-secret'] as string | undefined
req.client = {
project_id: client.project_id,
}
if (!clientId) {
return next(createError(401, 'Misisng client id'))
}
if (!clientSecret) {
return next(createError(401, 'Misisng client secret'))
}
const client = await db.client.findUnique({
where: {
id: clientId,
},
})
next()
}
if(!client) {
return next(createError(401, 'Invalid client id'))
}
if (!await verifyPassword(clientSecret, client.secret)) {
return next(createError(401, 'Invalid client secret'))
}
req.client = {
project_id: client.project_id,
}
next()
} catch (error) {
next(new HttpError(500, 'Failed verify client credentials'))
}
}

View File

@@ -1,9 +1,21 @@
import { NextFunction, Request, Response } from 'express'
import { db } from '../db'
import { v4 as uuid } from 'uuid'
import { hashPassword } from '../services/hash'
import { success } from '../responses/success'
export async function setup(req: Request, res: Response, next: NextFunction) {
try {
const counts = await db.$transaction([
db.organization.count(),
db.project.count(),
db.client.count(),
])
if (counts.some((count) => count > 0)) {
return res.json(success('Setup already done'))
}
const organization = await db.organization.create({
data: {
name: 'Acme Inc.',
@@ -16,20 +28,21 @@ export async function setup(req: Request, res: Response, next: NextFunction) {
organization_id: organization.id,
},
})
const secret = uuid()
const client = await db.client.create({
data: {
name: 'Acme Website Client',
project_id: project.id,
secret: '4bfc4a0b-37e0-4916-b634-95c6a32a2e77',
secret: await hashPassword(secret),
},
})
res.json({
organization,
project,
client,
})
res.json(
success({
clientId: client.id,
clientSecret: secret,
})
)
} catch (error) {
next(error)
}

View File

@@ -0,0 +1,7 @@
export async function hashPassword(password: string) {
return await Bun.password.hash(password);
}
export async function verifyPassword(password: string, hashedPassword: string) {
return await Bun.password.verify(password, hashedPassword);
}