From 26771cecdcc7961ee4058c6e29a7a156924225ed Mon Sep 17 00:00:00 2001 From: Douglas Barone Date: Thu, 15 Jun 2023 08:04:59 -0400 Subject: [PATCH] Inject user middleware --- package-lock.json | 8 ++--- package.json | 5 +++- .../migration.sql | 16 ++++++++++ prisma/schema.prisma | 18 ++++++++++++ prisma/seed.ts | 25 ++++++++++++++++ src/index.ts | 7 ++++- src/middleware/authorization.ts | 25 ---------------- src/middleware/injectUser.ts | 29 +++++++++++++++++++ 8 files changed, 102 insertions(+), 31 deletions(-) rename prisma/migrations/{20230614192351_init => 20230615120426_init}/migration.sql (54%) create mode 100644 prisma/seed.ts create mode 100644 src/middleware/injectUser.ts diff --git a/package-lock.json b/package-lock.json index 22cf7ba..1ca2b69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index bbd0c92..4cf205b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/prisma/migrations/20230614192351_init/migration.sql b/prisma/migrations/20230615120426_init/migration.sql similarity index 54% rename from prisma/migrations/20230614192351_init/migration.sql rename to prisma/migrations/20230615120426_init/migration.sql index 7b3a493..e2375bf 100644 --- a/prisma/migrations/20230614192351_init/migration.sql +++ b/prisma/migrations/20230615120426_init/migration.sql @@ -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"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 805f065..488b859 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -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 +} diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 0000000..499c114 --- /dev/null +++ b/prisma/seed.ts @@ -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) + }) diff --git a/src/index.ts b/src/index.ts index 8db830e..ea11691 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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 diff --git a/src/middleware/authorization.ts b/src/middleware/authorization.ts index e970eac..ca44f95 100644 --- a/src/middleware/authorization.ts +++ b/src/middleware/authorization.ts @@ -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) { diff --git a/src/middleware/injectUser.ts b/src/middleware/injectUser.ts new file mode 100644 index 0000000..0d849ec --- /dev/null +++ b/src/middleware/injectUser.ts @@ -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() +}