Inject user middleware

This commit is contained in:
Douglas Barone 2023-06-15 08:04:59 -04:00
parent 7c3bc91f39
commit 26771cecdc
8 changed files with 102 additions and 31 deletions

8
package-lock.json generated
View File

@ -19,7 +19,7 @@
"devDependencies": {
"@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2",
"@types/node": "^20.2.5",
"@types/node": "^20.3.1",
"nodemon": "^2.0.22",
"prisma": "^4.15.0",
"rimraf": "^5.0.1",
@ -214,9 +214,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "20.2.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz",
"integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ=="
"version": "20.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg=="
},
"node_modules/@types/qs": {
"version": "6.9.7",

View File

@ -10,13 +10,16 @@
"start": "node dist",
"dev": "nodemon --ext js,ts,mts,mjs,json,prisma ./src/index.ts --exec ts-node-esm"
},
"prisma": {
"seed": "ts-node --esm prisma/seed.ts"
},
"keywords": [],
"author": "Douglas Barone",
"license": "ISC",
"devDependencies": {
"@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2",
"@types/node": "^20.2.5",
"@types/node": "^20.3.1",
"nodemon": "^2.0.22",
"prisma": "^4.15.0",
"rimraf": "^5.0.1",

View File

@ -1,6 +1,9 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMIN', 'INSPECTOR', 'USER');
-- CreateEnum
CREATE TYPE "PrinterModel" AS ENUM ('m3655idn', 'm2040dn', 'p6235cdn');
-- CreateTable
CREATE TABLE "User" (
"id" SERIAL NOT NULL,
@ -15,5 +18,18 @@ CREATE TABLE "User" (
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Printer" (
"id" SERIAL NOT NULL,
"hostname" TEXT,
"friendlyName" TEXT,
"ip" TEXT NOT NULL,
"model" "PrinterModel" NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Printer_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");

View File

@ -29,3 +29,21 @@ model User {
roles Role[] @default([USER])
}
model Printer {
id Int @id @default(autoincrement())
hostname String?
friendlyName String?
ip String
model PrinterModel
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
enum PrinterModel {
m3655idn
m2040dn
p6235cdn
}

25
prisma/seed.ts Normal file
View File

@ -0,0 +1,25 @@
import { PrismaClient } from '@prisma/client'
export const prisma = new PrismaClient()
async function main() {
await prisma.printer.createMany({
data: [
{ friendlyName: 'p04', ip: '10.7.0.134', model: 'm3655idn' },
{ friendlyName: 'p05', ip: '10.7.0.135', model: 'm2040dn' },
{ friendlyName: 'p06', ip: '10.7.0.136', model: 'm2040dn' },
{ friendlyName: 'p07', ip: '10.7.0.137', model: 'm2040dn' },
{ friendlyName: 'p08', ip: '10.7.0.138', model: 'p6235cdn' }
]
})
}
main()
.then(() => {
prisma.$disconnect()
})
.catch(error => {
console.error(error)
prisma.$disconnect()
process.exit(1)
})

View File

@ -1,12 +1,15 @@
import 'dotenv/config'
import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
import { login } from './authentication.js'
import {
authenticatedMiddleware,
hasRolesMiddleware
} from './middleware/authorization.js'
import { injectUserMiddleware } from './middleware/injectUser.js'
import { RequestWithUser } from './types.js'
import { login } from './authentication.js'
import { UserController } from './controllers/UserController.js'
const app = express()
@ -15,6 +18,8 @@ const PORT = process.env.PORT || 3000
app.use('/', express.static('public'))
app.use(injectUserMiddleware)
app.use(bodyParser.json())
// Test route

View File

@ -3,35 +3,12 @@ import { authenticate } from '../authentication.js'
import { RequestWithUser } from '../types.js'
import { Role } from '@prisma/client'
function getToken(req: Request) {
const authHeader = req.headers.authorization as string
if (!authHeader) return null
const [type, token] = authHeader.split(' ')
if (type !== 'Bearer') throw new Error('Expected a Bearer token')
return token
}
async function injectUser(req: RequestWithUser) {
const token = getToken(req)
if (!token) return null
const user = await authenticate(token)
req.user = user
}
export async function authenticatedMiddleware(
req: RequestWithUser,
res: Response,
next: NextFunction
) {
try {
await injectUser(req)
if (!req.user) {
res.status(401).json({ error: 'Must be logged in' })
return
@ -50,8 +27,6 @@ export async function hasRolesMiddleware(roles: Role[]) {
next: NextFunction
) {
try {
await injectUser(req)
const userRoles = req.user?.roles
if (userRoles === undefined) {

View File

@ -0,0 +1,29 @@
import { NextFunction, Request, Response } from 'express'
import { RequestWithUser } from '../types.js'
import { authenticate } from '../authentication.js'
function getToken(req: Request) {
const authHeader = req.headers.authorization as string
if (!authHeader) return null
const [type, token] = authHeader.split(' ')
if (type !== 'Bearer') throw new Error('Expected a Bearer token')
return token
}
export async function injectUserMiddleware(
req: RequestWithUser,
res: Response,
next: NextFunction
) {
const token = getToken(req)
if (token) {
const user = await authenticate(token)
req.user = user
}
next()
}