From e1b64fa7044c84eb8b2b3cbfbef535df2764e642 Mon Sep 17 00:00:00 2001 From: Benn Bollay Date: Wed, 2 Dec 2020 12:08:10 -0800 Subject: [PATCH] Add authorization --- package.json | 2 ++ src/authorize.ts | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/index.ts | 3 ++- 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/authorize.ts diff --git a/package.json b/package.json index f9ae75f..532fbc8 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "dependencies": { "aws-sdk": "^2.801.0", "express": "^4.17.1", + "jsonwebtoken": "^8.5.1", "@types/express": "^4.17.9", + "@types/jsonwebtoken": "^8.5.0", "@types/node": "^10.15.3", "prettier": "^2.2.1", "typescript": "^4.1.2" diff --git a/src/authorize.ts b/src/authorize.ts new file mode 100644 index 0000000..7f8effb --- /dev/null +++ b/src/authorize.ts @@ -0,0 +1,45 @@ +const { DynamoDB } = require('aws-sdk'); + +import { Request, Response, NextFunction } from 'express'; + +import jwt from 'jsonwebtoken'; + +const ddb = new DynamoDB(); + +const getUserPerms = async (user: any): Promise => { + const result = await ddb.scan({TableName:'users' }) .promise(); + return result.Items?result.Items.map((e: any) => e.userPermissions.S as string) : []; +}; + +const authenticateUser = async(token: any): Promise => { + const parsed = jwt.decode(token); + if (!parsed) + throw new Error('Unauthorized'); + + return parsed.sub; +}; + +// Validate that there's a permission 'catName:1' in the permissions for the user. +const testPerm = async (perm: any, catName: any): Promise =>{ + return [...perm.matchAll(`/(${catName}):(\d)/g`)].map((e) => e[2]).filter((p) => p > 0).length > 0; +}; + +const authorize = async (req: Request, res: Response, next: NextFunction) => { + var authHeader = req.headers['authentication']; + if (!authHeader) { + return res.status(404); + } + + var token = authenticateUser(authHeader as string); + if (!token) { return res.status(404); } + + var perms = await getUserPerms(req.params.user); + for (var i = 0; i < perms.length; i++) { + if (testPerm(perms[i], req.params.catName)) + return next(); + } + + return res.status(404); +}; + +export { authorize }; diff --git a/src/index.ts b/src/index.ts index d3e4756..d2e1ca0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,11 @@ import express from 'express'; +import { authorize } from './authorize'; import { getImage } from './images'; const app = express(); const PORT = 8123; -app.get('/cat/:catName', async (req, res) => { +app.get('/cat/:catName', authorize, async (req, res) => { const catUrl = await getImage(req.params.catName); if (!catUrl) { return res.status(404);