From f78c71acd5c36bada8359688990ceb58a49d75d9 Mon Sep 17 00:00:00 2001 From: hmzsjd Date: Tue, 25 Jan 2022 20:33:19 -0700 Subject: [PATCH 1/4] initial commit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d16a46cac..57a1514f3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Using JSON Web Tokens +# Using JSON Web Tokens. ## Introduction From 05dfafdd3ced51f169bf3eae47dc7c7ecfd38cc1 Mon Sep 17 00:00:00 2001 From: hmzsjd Date: Tue, 25 Jan 2022 22:11:40 -0700 Subject: [PATCH 2/4] 1 test failing --- api/auth/auth-middleware.js | 100 +++++++++--------- api/auth/auth-router.js | 47 +++++++-- api/auth/auth-token.js | 18 ++++ api/secrets/index.js | 2 +- api/users/users-model.js | 84 ++++++--------- data/auth.db3 | Bin 32768 -> 32768 bytes package-lock.json | 202 ++++++++++++++++++++++++++++++++++-- package.json | 3 +- 8 files changed, 331 insertions(+), 125 deletions(-) create mode 100644 api/auth/auth-token.js diff --git a/api/auth/auth-middleware.js b/api/auth/auth-middleware.js index c603d37c7..bd7ff8bb9 100644 --- a/api/auth/auth-middleware.js +++ b/api/auth/auth-middleware.js @@ -1,72 +1,66 @@ const { JWT_SECRET } = require("../secrets"); // use this secret! +const User = require("../users/users-model.js"); +const jwt = require('jsonwebtoken'); const restricted = (req, res, next) => { - /* - If the user does not provide a token in the Authorization header: - status 401 - { - "message": "Token required" - } - - If the provided token does not verify: - status 401 - { - "message": "Token invalid" - } + const token = req.headers.authorization; - Put the decoded token in the req object, to make life easier for middlewares downstream! - */ -} + if (!token) { + return next({ status: 401, message: "Token required" }); + } -const only = role_name => (req, res, next) => { - /* - If the user does not provide a token in the Authorization header with a role_name - inside its payload matching the role_name passed to this function as its argument: - status 403 - { - "message": "This is not for you" + jwt.verify(token, JWT_SECRET, (err, decoded) => { + if (err) { + return next({ status: 401, message: "Token invalid" }); } + req.decodedJwt = decoded; + next(); + }); +}; - Pull the decoded token from the req object, to avoid verifying it again! - */ -} - +const only = (role_name) => (req, res, next) => { + if (req.decodedJwt.role_name === role_name) { + next(); + } else { + next({ status: 403, message: "This is not for you" }); + } +}; const checkUsernameExists = (req, res, next) => { - /* - If the username in req.body does NOT exist in the database - status 401 - { - "message": "Invalid credentials" - } - */ -} + const {username} = req.body + User.findBy({username}) + .then(user => { + if (!user) { + next({ status: 401, message: 'Invalid credentials'}) + } + else { + next() + } + }) + .catch(next) + +}; const validateRoleName = (req, res, next) => { - /* - If the role_name in the body is valid, set req.role_name to be the trimmed string and proceed. - If role_name is missing from req.body, or if after trimming it is just an empty string, - set req.role_name to be 'student' and allow the request to proceed. - - If role_name is 'admin' after trimming the string: - status 422 - { - "message": "Role name can not be admin" - } - - If role_name is over 32 characters after trimming the string: - status 422 - { - "message": "Role name can not be longer than 32 chars" - } - */ -} + const { role_name } = req.body + if (!role_name || role_name.trim() === '') { + req.role_name = 'student' + next() + } else if (role_name.trim() === 'admin') { + next({ status: 422, message: 'Role name can not be admin' }) + } else if (role_name.trim().length > 32) { + next({ status: 422, message: 'Role name can not be longer than 32 chars' }) + } else { + req.role_name = role_name.trim() + next() + } +}; module.exports = { restricted, checkUsernameExists, validateRoleName, only, -} +}; diff --git a/api/auth/auth-router.js b/api/auth/auth-router.js index c723c2da8..8358bd75d 100644 --- a/api/auth/auth-router.js +++ b/api/auth/auth-router.js @@ -1,19 +1,31 @@ const router = require("express").Router(); const { checkUsernameExists, validateRoleName } = require('./auth-middleware'); const { JWT_SECRET } = require("../secrets"); // use this secret! +const {tokenBuilder} = require('./auth-token') +const bcrypt = require('bcryptjs') +const User = require('../users/users-model') router.post("/register", validateRoleName, (req, res, next) => { - /** - [POST] /api/auth/register { "username": "anna", "password": "1234", "role_name": "angel" } - response: - status 201 - { - "user"_id: 3, - "username": "anna", - "role_name": "angel" - } - */ + const user = { + username: req.body.username, + password: req.body.password, + role_name: req.role_name + } + + const hash = bcrypt.hashSync(user.password, 8) + user.password = hash + + User.add(user) + .then(u => { + res.status(201).json({ + user_id: u.user_id, + username: u.username, + role_name: u.role_name + }) + }) + .catch(next) + }); @@ -37,6 +49,21 @@ router.post("/login", checkUsernameExists, (req, res, next) => { "role_name": "admin" // the role of the authenticated user } */ + let { username, password } = req.body + + User.findBy({ username }) + .then(([user]) => { + if (user && bcrypt.compareSync(password, user.password)) { + const token = tokenBuilder(user) + res.status(200).json({ message: `${user.username} is back!`, token }) + } else { + next({ status: 401, message: 'Invalid Credentials' }) + } + }) + .catch(next) + + + }); module.exports = router; diff --git a/api/auth/auth-token.js b/api/auth/auth-token.js new file mode 100644 index 000000000..b0bdb9336 --- /dev/null +++ b/api/auth/auth-token.js @@ -0,0 +1,18 @@ +const jwt = require("jsonwebtoken"); +const { JWT_SECRET } = require("../secrets"); + +function tokenBuilder(user) { + const payload = { + subject: user.user_id, + username: user.username, + role_name: user.role_name + } + const options = { + expiresIn: '1d' + } + return jwt.sign(payload, JWT_SECRET, options) +} + +module.exports = { + tokenBuilder, +} \ No newline at end of file diff --git a/api/secrets/index.js b/api/secrets/index.js index 1a125b81e..7058c6526 100644 --- a/api/secrets/index.js +++ b/api/secrets/index.js @@ -7,5 +7,5 @@ developers cloning this repo won't be able to run the project as is. */ module.exports = { - + JWT_SECRET: process.env.JWT_SECRET || 'shh', } diff --git a/api/users/users-model.js b/api/users/users-model.js index 7a2064834..c86a17a52 100644 --- a/api/users/users-model.js +++ b/api/users/users-model.js @@ -1,52 +1,24 @@ -const db = require('../../data/db-config.js'); +const db = require("../../data/db-config"); function find() { - /** - You will need to join two tables. - Resolves to an ARRAY with all users. - - [ - { - "user_id": 1, - "username": "bob", - "role_name": "admin" - }, - { - "user_id": 2, - "username": "sue", - "role_name": "instructor" - } - ] - */ + return db("users") + .join("roles", "users.role_id", "roles.role_id") + .select("users.user_id", "users.username", "role.role_name"); } function findBy(filter) { - /** - You will need to join two tables. - Resolves to an ARRAY with all users that match the filter condition. - - [ - { - "user_id": 1, - "username": "bob", - "password": "$2a$10$dFwWjD8hi8K2I9/Y65MWi.WU0qn9eAVaiBoRSShTvuJVGw8XpsCiq", - "role_name": "admin", - } - ] - */ + return db("users as u") + .join("roles as r", "u.role_id", "r.role_id") + .select("u.user_id", "u.username", "r.role_name", "u.password") + .where(filter); } function findById(user_id) { - /** - You will need to join two tables. - Resolves to the user with the given user_id. - - { - "user_id": 2, - "username": "sue", - "role_name": "instructor" - } - */ + return db("users as u") + .join("roles as r", "u.role_id", "r.role_id") + .select("u.user_id", "u.username", "r.role_name") + .where("u.user_id", user_id) + .first(); } /** @@ -67,21 +39,27 @@ function findById(user_id) { "role_name": "team lead" } */ -async function add({ username, password, role_name }) { // done for you - let created_user_id - await db.transaction(async trx => { - let role_id_to_use - const [role] = await trx('roles').where('role_name', role_name) + +async function add({ username, password, role_name }) { + // done for you + let created_user_id; + await db.transaction(async (trx) => { + let role_id_to_use; + const [role] = await trx("roles").where("role_name", role_name); if (role) { - role_id_to_use = role.role_id + role_id_to_use = role.role_id; } else { - const [role_id] = await trx('roles').insert({ role_name: role_name }) - role_id_to_use = role_id + const [role_id] = await trx("roles").insert({ role_name: role_name }); + role_id_to_use = role_id; } - const [user_id] = await trx('users').insert({ username, password, role_id: role_id_to_use }) - created_user_id = user_id - }) - return findById(created_user_id) + const [user_id] = await trx("users").insert({ + username, + password, + role_id: role_id_to_use, + }); + created_user_id = user_id; + }); + return findById(created_user_id); } module.exports = { diff --git a/data/auth.db3 b/data/auth.db3 index 568bc34c7877fd4d47b42a561434f8885c50ca00..997d152cd496dd8ba37b6294f0d48dcfb141a892 100644 GIT binary patch delta 367 zcmZo@U}|V!njkI6&cMLH0mLxCHc`izk$q#rYQb%$&?XW>J1lYB94A6SFpFc3x^ld~RlXQDRAEeqOOSBeN;z zACr*<#?18 z`x)yOd6)Z?1{p-9hm`n*gr(~z>FJjjl({oaF3fjlWS+b;-|2YHyPyUbm&w-A+ b$uG$X4HZLXc4lG5;?h(mHfCYYr2HfRI+9_2 delta 793 zcmZuuO=}ZT6n!(#)}*z4O^XBxC@q0fKWdUDX-8L0YvY)4CJkv!1Ae?@l9_3zGnsia zO(H_$!o5<#g|6LeSN#DZ3T_p#2)faQn}Q(jd^7z})OUH8!@ZnyFXwizzxnULtAq+DvsoR7NvJ~2; zUMFyvfoFoNM!kJ=O;c>_Xr@7)$NGnQzMv02`4yTz9qEG*M2O?cb;B88AsE#R;@ED@ zG3@{YK^V(xn$hRa-2vza`igeYJ39F_x-dcdVT9S|!a+F7{N}O&7!LYeZ)X-+0Bs`+ zjSr4_u@xE`8r)z$hVS+;RkK>{L=!j~k42TG@)AkUUQXHqspehvd^&k8KUv}VWRXwj z%8I1xr6OK6YExQVm`!q6a82n50L(*(rIuc5CuaBsJEkcqtK&E;$%7|D!8qZgZE!*1Eu7 z)kLh)#I3Wva3n}8 FzW_aH=L-M; diff --git a/package-lock.json b/package-lock.json index 0736ef5e2..257015f57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "cors": "^2.8.5", "express": "^4.17.1", "helmet": "^4.6.0", - "knex": "^0.95.14", + "jsonwebtoken": "^8.5.1", + "knex": "^0.95.15", "sqlite3": "^5.0.2" }, "devDependencies": { @@ -1717,6 +1718,11 @@ "node-int64": "^0.4.0" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2392,6 +2398,14 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4609,6 +4623,35 @@ "node": ">=6" } }, + "node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -4624,6 +4667,25 @@ "node": ">=0.6.0" } }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/jwt-decode": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", @@ -4649,9 +4711,9 @@ } }, "node_modules/knex": { - "version": "0.95.14", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.14.tgz", - "integrity": "sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg==", + "version": "0.95.15", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.15.tgz", + "integrity": "sha512-Loq6WgHaWlmL2bfZGWPsy4l8xw4pOE+tmLGkPG0auBppxpI0UcK+GYCycJcqz9W54f2LiGewkCVLBm3Wq4ur/w==", "dependencies": { "colorette": "2.0.16", "commander": "^7.1.0", @@ -4769,12 +4831,47 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -8568,6 +8665,11 @@ "node-int64": "^0.4.0" } }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -9094,6 +9196,14 @@ "safer-buffer": "^2.1.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -10811,6 +10921,30 @@ "minimist": "^1.2.5" } }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -10823,6 +10957,25 @@ "verror": "1.10.0" } }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "jwt-decode": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", @@ -10845,9 +10998,9 @@ "dev": true }, "knex": { - "version": "0.95.14", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.14.tgz", - "integrity": "sha512-j4qLjWySrC/JRRVtOpoR2LcS1yBOsd7Krc6mEukPvmTDX/w11pD52Pq9FYR56/kLXGeAV8jFdWBjsZFi1mscWg==", + "version": "0.95.15", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.15.tgz", + "integrity": "sha512-Loq6WgHaWlmL2bfZGWPsy4l8xw4pOE+tmLGkPG0auBppxpI0UcK+GYCycJcqz9W54f2LiGewkCVLBm3Wq4ur/w==", "requires": { "colorette": "2.0.16", "commander": "^7.1.0", @@ -10918,12 +11071,47 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", diff --git a/package.json b/package.json index e3c921091..df3baf8b3 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "cors": "^2.8.5", "express": "^4.17.1", "helmet": "^4.6.0", - "knex": "^0.95.14", + "jsonwebtoken": "^8.5.1", + "knex": "^0.95.15", "sqlite3": "^5.0.2" }, "repository": { From 0a45f5b47467479f018ac795ea309617cbd27012 Mon Sep 17 00:00:00 2001 From: hmzsjd Date: Tue, 25 Jan 2022 22:57:39 -0700 Subject: [PATCH 3/4] MVP - all tests passing --- api/users/users-model.js | 2 +- data/auth.db3 | Bin 32768 -> 32768 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/api/users/users-model.js b/api/users/users-model.js index c86a17a52..ec29919a3 100644 --- a/api/users/users-model.js +++ b/api/users/users-model.js @@ -3,7 +3,7 @@ const db = require("../../data/db-config"); function find() { return db("users") .join("roles", "users.role_id", "roles.role_id") - .select("users.user_id", "users.username", "role.role_name"); + .select("users.user_id", "users.username", "roles.role_name"); } function findBy(filter) { diff --git a/data/auth.db3 b/data/auth.db3 index 997d152cd496dd8ba37b6294f0d48dcfb141a892..376bcd4c1d1f78a1e74c267002f2e2c0ec58e400 100644 GIT binary patch delta 177 zcmZo@U}|V!njp={F;T{ukz->*x;`Vz<`eoh20Sc$cNzG1@)z=}^WEJnC~%g~%Y%iD zLA;Tbv9vg~$VkN~QN_SQ#Xrp7A~7V@C9vEvGvB1F(!wn)Gpe*Wz#uJL-@+oaI6EvW z$v4s1F)Z06%)qJ0&o$E|Nsno=dj4G=7Ji@wKlwlMKj#NpU~raSnUh%@VmJ$oWys9V SEX-J3n##n+EXJ0ol`3w2gHwy|#@=sRJzY7$5 o&cOeZ|0DnN&4LCu`6u74=MXexW@i>=EG|uDVq+HOOv+CJ0NVx^5&!@I From 7a39ae9d74b7931fe17fafab39659b589489d8c2 Mon Sep 17 00:00:00 2001 From: hmzsjd Date: Thu, 27 Jan 2022 22:39:08 -0700 Subject: [PATCH 4/4] testing branch --- api/users/users-router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/users/users-router.js b/api/users/users-router.js index 48baddc06..6b209ddca 100644 --- a/api/users/users-router.js +++ b/api/users/users-router.js @@ -3,7 +3,7 @@ const Users = require("./users-model.js"); const { restricted, only } = require("../auth/auth-middleware.js"); /** - [GET] /api/users + [GET] /api/users/ This endpoint is RESTRICTED: only authenticated clients should have access.