diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..7937d0f03 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,82 @@ +# Common settings that generally should always be used with your language specific settings + + +*.html linguist-vendored=true +*.ipynb linguist-vendored=true + +# Linguist::FileBlob.new("./*.html").vendored? # => true +# Auto detect text files and perform LF normalization +# https://www.davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/ +* text=auto + +# +# The above will handle all files NOT found below +# + +# Documents +*.bibtex text diff=bibtex +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain +*.md text diff=markdown +*.tex text diff=tex +*.adoc text +*.textile text +*.mustache text +*.csv text +*.tab text +*.tsv text +*.txt text +*.sql text +*.ps1 text eol=crlf + +# Graphics +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.tif binary +*.tiff binary +*.ico binary +# SVG treated as an asset (binary) by default. +*.svg text +# If you want to treat it as binary, +# use the following line instead. +# *.svg binary +*.eps binary + +# Scripts +*.bash text eol=lf +*.fish text eol=lf +*.sh text eol=lf +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf + +# Serialisation +*.json text +*.toml text +*.xml text +*.yaml text +*.yml text + +# Archives +*.7z binary +*.gz binary +*.tar binary +*.tgz binary +*.zip binary + +# Text files where line endings should be preserved +*.patch -text + +# +# Exclude files from exporting +# diff --git a/api/auth/auth-middleware.js b/api/auth/auth-middleware.js deleted file mode 100644 index c603d37c7..000000000 --- a/api/auth/auth-middleware.js +++ /dev/null @@ -1,72 +0,0 @@ -const { JWT_SECRET } = require("../secrets"); // use this secret! - -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" - } - - Put the decoded token in the req object, to make life easier for middlewares downstream! - */ -} - -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" - } - - Pull the decoded token from the req object, to avoid verifying it again! - */ -} - - -const checkUsernameExists = (req, res, next) => { - /* - If the username in req.body does NOT exist in the database - status 401 - { - "message": "Invalid credentials" - } - */ -} - - -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" - } - */ -} - -module.exports = { - restricted, - checkUsernameExists, - validateRoleName, - only, -} diff --git a/api/auth/auth-router.js b/api/auth/auth-router.js deleted file mode 100644 index c723c2da8..000000000 --- a/api/auth/auth-router.js +++ /dev/null @@ -1,42 +0,0 @@ -const router = require("express").Router(); -const { checkUsernameExists, validateRoleName } = require('./auth-middleware'); -const { JWT_SECRET } = require("../secrets"); // use this secret! - -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" - } - */ -}); - - -router.post("/login", checkUsernameExists, (req, res, next) => { - /** - [POST] /api/auth/login { "username": "sue", "password": "1234" } - - response: - status 200 - { - "message": "sue is back!", - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ETC.ETC" - } - - The token must expire in one day, and must provide the following information - in its payload: - - { - "subject" : 1 // the user_id of the authenticated user - "username" : "bob" // the username of the authenticated user - "role_name": "admin" // the role of the authenticated user - } - */ -}); - -module.exports = router; diff --git a/api/secrets/index.js b/api/secrets/index.js deleted file mode 100644 index 1a125b81e..000000000 --- a/api/secrets/index.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - Fix this module so other modules can require JWT_SECRET into them. - Use the || operator to fall back to the string "shh" to handle the situation - where the process.env does not have JWT_SECRET. - - If no fallback is provided, TESTS WON'T WORK and other - developers cloning this repo won't be able to run the project as is. - */ -module.exports = { - -} diff --git a/api/users/users-model.js b/api/users/users-model.js deleted file mode 100644 index 7a2064834..000000000 --- a/api/users/users-model.js +++ /dev/null @@ -1,92 +0,0 @@ -const db = require('../../data/db-config.js'); - -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" - } - ] - */ -} - -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", - } - ] - */ -} - -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" - } - */ -} - -/** - Creating a user requires a single insert (into users) if the role record with the given - role_name already exists in the db, or two inserts (into roles and then into users) - if the given role_name does not exist yet. - - When an operation like creating a user involves inserts to several tables, - we want the operation to succeed or fail as a whole. It would not do to - insert a new role record and then have the insertion of the user fail. - - In situations like these we use transactions: if anything inside the transaction - fails, all the database changes in it are rolled back. - - { - "user_id": 7, - "username": "anna", - "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) - if (role) { - 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 [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 = { - add, - find, - findBy, - findById, -}; diff --git a/data/auth.db3 b/data/auth.db3 deleted file mode 100644 index 568bc34c7..000000000 Binary files a/data/auth.db3 and /dev/null differ diff --git a/jest.config.js b/jest.config.js index b150ac59c..2300e9500 100644 --- a/jest.config.js +++ b/jest.config.js @@ -191,4 +191,4 @@ module.exports = { // Whether to use watchman for file crawling // watchman: true, -}; +}; \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 000000000..3ebd35a0f --- /dev/null +++ b/makefile @@ -0,0 +1,5 @@ +git: + git add . + git commit -m "$m-update" + git push -u origin bryan-guner +# just type make into the terminal to exicute these commands! diff --git a/notes/commands.md b/notes/commands.md new file mode 100644 index 000000000..c5ab3fd1f --- /dev/null +++ b/notes/commands.md @@ -0,0 +1,6 @@ +```sh +git init +git add . +git commit -m"update" +git push -u origin bryan-guner +``` diff --git a/notes/notes.md b/notes/notes.md new file mode 100644 index 000000000..3536202fa --- /dev/null +++ b/notes/notes.md @@ -0,0 +1,29 @@ +## Parts of a token + +header +payload +subject +name +issues +verify signature + +base 64 encoded + +> Tokens CAN be encrypted + +> Tokens can be larger than cookies + +> Tokens are Client side + +- client does most of work + +> Sessions are server side + +## Install JSON Web Token + +[] npm i jsonwebtoken\ + +## Install bcrypt + +https://www.npmjs.com/package/bcrypt +[] npm install bcrypt diff --git a/notes/session-vs-token-auth.png b/notes/session-vs-token-auth.png new file mode 100644 index 000000000..f1fca0e4c Binary files /dev/null and b/notes/session-vs-token-auth.png differ diff --git a/package-lock.json b/package-lock.json index 398e340ad..78f362b4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "cors": "^2.8.5", "express": "^4.17.1", "helmet": "^4.6.0", + "jsonwebtoken": "^8.5.1", "knex": "^0.95.7", "sqlite3": "^5.0.2" }, @@ -1968,6 +1969,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.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -2813,6 +2819,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", @@ -5522,6 +5536,40 @@ "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/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "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.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -5537,6 +5585,25 @@ "verror": "1.10.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", @@ -5705,12 +5772,47 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, + "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/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", @@ -10977,6 +11079,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.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -11645,6 +11752,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", @@ -13767,6 +13882,35 @@ "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": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -13779,6 +13923,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", @@ -13897,12 +14060,47 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, + "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=" + }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", diff --git a/package.json b/package.json deleted file mode 100644 index 88f726929..000000000 --- a/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "node-auth2-project", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "server": "nodemon index.js", - "migrate": "knex migrate:latest", - "rollback": "knex migrate:rollback", - "seed": "knex seed:run", - "test": "cross-env NODE_ENV=testing jest --watch --verbose --runInBand" - }, - "devDependencies": { - "@types/jest": "^26.0.24", - "cross-env": "^7.0.3", - "eslint": "^7.30.0", - "jest": "^26.6.3", - "jwt-decode": "^3.1.2", - "nodemon": "^2.0.12", - "supertest": "^6.1.3" - }, - "dependencies": { - "bcryptjs": "^2.4.3", - "cors": "^2.8.5", - "express": "^4.17.1", - "helmet": "^4.6.0", - "knex": "^0.95.7", - "sqlite3": "^5.0.2" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/LambdaSchool/node-auth2-project.git" - } -}