Repository: Code-Pop/authentication_course Branch: master Commit: 3c883daad161 Files: 24 Total size: 17.9 KB Directory structure: gitextract_ix0n5d8h/ ├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── README.md ├── _server.js ├── babel.config.js ├── db/ │ └── events.json ├── package.json ├── postcss.config.js ├── public/ │ └── index.html ├── server.js ├── src/ │ ├── App.vue │ ├── assets/ │ │ └── styles/ │ │ └── global.scss │ ├── components/ │ │ ├── AppNav.vue │ │ ├── EventCard.vue │ │ ├── LoginUser.vue │ │ └── RegisterUser.vue │ ├── main.js │ ├── router.js │ ├── store.js │ └── views/ │ ├── Authenticate.vue │ ├── Dashboard.vue │ └── Home.vue └── vue.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .browserslistrc ================================================ > 1% last 2 versions not ie <= 8 ================================================ FILE: .eslintrc.js ================================================ module.exports = { root: true, env: { node: true }, extends: ["plugin:vue/recommended", "standard"], rules: { "no-console": process.env.NODE_ENV === "production" ? "error" : "off", "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", "vue/max-attributes-per-line": ["error", { "singleline": 4, "multiline": { "max": 1, "allowFirstLine": false } }] }, parserOptions: { parser: "babel-eslint" } }; ================================================ FILE: .gitignore ================================================ .DS_Store node_modules /dist # local env files .env.local .env.*.local db/user.json # Log files npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw* ================================================ FILE: README.md ================================================ # authentication_course ## Project setup ``` npm install ``` ### Compiles and hot-reloads for development ``` npm run serve ``` ### Same as above and start backend server ``` npm run start ``` ### Compiles and minifies for production ``` npm run build ``` ### Run your tests ``` npm run test ``` ### Lints and fixes files ``` npm run lint ``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). ================================================ FILE: _server.js ================================================ var express = require('express') var jwt = require('jsonwebtoken') var cors = require('cors') var bodyParser = require('body-parser') var fs = require('fs') var events = require('./db/events.json') const app = express() app.use(cors()) app.use(bodyParser.json()) app.get('/', (req, res) => { res.json({ message: 'Welcome to the API.' }) }) app.get('/dashboard', verifyToken, (req, res) => { jwt.verify(req.token, 'the_secret_key', err => { if (err) { res.sendStatus(401) } else { res.json({ events: events }) } }) }) app.post('/register', (req, res) => { if (req.body) { const user = { name: req.body.name, email: req.body.email, password: req.body.password // You'll want to encrypt the password in a live app } var data = JSON.stringify(user, null, 2) fs.writeFile('db/user.json', data, err => { if (err) { console.log(err) } else { console.log('Added user to user.json') } }) // The secret key should be an evironment variable in a live app const token = jwt.sign({ user }, 'the_secret_key') res.json({ token, email: user.email, name: user.name }) } else { res.sendStatus(401) } }) app.post('/login', (req, res) => { var userDB = fs.readFileSync('./db/user.json') var userInfo = JSON.parse(userDB) if ( req.body && req.body.email === userInfo.email && req.body.password === userInfo.password ) { // The secret key should be an environment variable in a live app const token = jwt.sign({ userInfo }, 'the_secret_key') res.json({ token, email: userInfo.email, name: userInfo.name }) } else { res.sendStatus(401) } }) function verifyToken (req, res, next) { const bearerHeader = req.headers['authorization'] if (typeof bearerHeader !== 'undefined') { const bearer = bearerHeader.split(' ') const bearerToken = bearer[1] req.token = bearerToken next() } else { res.sendStatus(401) } } app.listen(3000, () => { console.log('Server started on port 3000') }) ================================================ FILE: babel.config.js ================================================ module.exports = { presets: ["@vue/app"] }; ================================================ FILE: db/events.json ================================================ { "events": [ { "id": "1234", "title": "Puppy Parade", "time": "12:00", "date": "Feb 22, 2022" }, { "id": "1584", "title": "Cat Cabaret", "time": "9:00", "date": "March 4, 2022" }, { "id": "2794", "title": "Doggy Day", "time": "1:00", "date": "June 12, 2022" }, { "id": "4619", "title": "Feline Frenzy", "time": "8:00", "date": "July 28, 2022" } ] } ================================================ FILE: package.json ================================================ { "name": "authentication_course", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint", "start": "nodemon server.js & vue-cli-service serve" }, "dependencies": { "axios": "^0.18.0", "body-parser": "^1.18.3", "cors": "^2.8.5", "eslint-config-standard": "^12.0.0", "eslint-plugin-import": "^2.16.0", "express": "^4.16.4", "jsonwebtoken": "^8.4.0", "nodemon": "^1.18.10", "sqlite3": "^4.0.6", "vue": "^2.5.22", "vue-router": "^3.0.1", "vuex": "^3.0.1" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.4.0", "@vue/cli-plugin-eslint": "^3.4.0", "@vue/cli-service": "^3.4.0", "@vue/eslint-config-prettier": "^4.0.1", "babel-eslint": "^10.0.1", "eslint": "^5.8.0", "eslint-plugin-node": "^8.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-standard": "^4.0.0", "eslint-plugin-vue": "^5.0.0", "node-sass": "^4.11.0", "sass-loader": "^7.1.0", "vue-template-compiler": "^2.5.21" } } ================================================ FILE: postcss.config.js ================================================ module.exports = { plugins: { autoprefixer: {} } }; ================================================ FILE: public/index.html ================================================ authentication_course
================================================ FILE: server.js ================================================ const express = require('express') const jwt = require('jsonwebtoken') const cors = require('cors') const bodyParser = require('body-parser') const fs = require('fs') const events = require('./db/events.json') const app = express() app.use(cors()) app.use(bodyParser.json()) app.get('/', (req, res) => { res.json({ message: 'Welcome to the API.' }) }) app.get('/dashboard', verifyToken, (req, res) => { jwt.verify(req.token, 'the_secret_key', err => { if (err) { res.sendStatus(401) } else { res.json({ events: events }) } }) }) app.post('/register', (req, res) => { if (req.body) { const user = { name: req.body.name, email: req.body.email, password: req.body.password // In a production app, you'll want to encrypt the password } const data = JSON.stringify(user, null, 2) var dbUserEmail = require('./db/user.json').email if (dbUserEmail === req.body.email) { res.sendStatus(400) } else { fs.writeFile('./db/user.json', data, err => { if (err) { console.log(err + data) } else { const token = jwt.sign({ user }, 'the_secret_key') // In a production app, you'll want the secret key to be an environment variable res.json({ token, email: user.email, name: user.name }) } }) } } else { res.sendStatus(400) } }) app.post('/login', (req, res) => { const userDB = fs.readFileSync('./db/user.json') const userInfo = JSON.parse(userDB) if ( req.body && req.body.email === userInfo.email && req.body.password === userInfo.password ) { const token = jwt.sign({ userInfo }, 'the_secret_key') // In a production app, you'll want the secret key to be an environment variable res.json({ token, email: userInfo.email, name: userInfo.name }) } else { res.sendStatus(400) } }) // MIDDLEWARE function verifyToken (req, res, next) { const bearerHeader = req.headers['authorization'] if (typeof bearerHeader !== 'undefined') { const bearer = bearerHeader.split(' ') const bearerToken = bearer[1] req.token = bearerToken next() } else { res.sendStatus(401) } } app.listen(3000, () => { console.log('Server started on port 3000') }) ================================================ FILE: src/App.vue ================================================ ================================================ FILE: src/assets/styles/global.scss ================================================ body { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; padding: 0em; margin: 0em; } a:visited { color: #2c3e50; } .button, button { display: flex; align-items: center; justify-content: center; width: 5em; height: 2em; margin: 0.5em; border-radius: 5px; background: linear-gradient(to right, #16c0b0, #84cf6a); font-size: 1em; color: white; border: none; outline: none; } form { display: flex; align-items: center; flex-direction: column; width: 15em; margin-bottom: 2em; p { color: red; } } input { display: block; box-sizing: border-box; width: 100%; height: 2.6em; padding: 0.5em; margin-bottom: 1em; font: 1em 'Avenir', Helvetica, sans-serif; } h1 { margin-top: 0; } ================================================ FILE: src/components/AppNav.vue ================================================ ================================================ FILE: src/components/EventCard.vue ================================================ ================================================ FILE: src/components/LoginUser.vue ================================================ ================================================ FILE: src/components/RegisterUser.vue ================================================ ================================================ FILE: src/main.js ================================================ import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import axios from 'axios' Vue.config.productionTip = false new Vue({ router, store, render: h => h(App), created() { const userString = localStorage.getItem('user') if (userString) { const userData = JSON.parse(userString) this.$store.commit('SET_USER_DATA', userData) } // axios.interceptors.response.use( response => response, error => { console.log(error.response) if (error.response.status === 401) { this.$router.push('/') this.$store.dispatch('logout') } return Promise.reject(error) } ) } }).$mount('#app') ================================================ FILE: src/router.js ================================================ import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import Dashboard from './views/Dashboard.vue' import Authenticate from './views/Authenticate.vue' Vue.use(Router) const router = new Router({ mode: 'history', base: process.env.BASE_URL, routes: [ { path: '/', name: 'home', component: Home }, { path: '/dashboard', name: 'dashboard', component: Dashboard }, { path: '/authenticate', name: 'authenticate', component: Authenticate } ] }) router.beforeEach((to, from, next) => { // redirect to login page if user is not logged in and trying to access a restricted page const publicPages = ['/authenticate', '/'] const authRequired = !publicPages.includes(to.path) const loggedIn = localStorage.getItem('user') if (authRequired && !loggedIn) { return next('/authenticate') } next() }) export default router ================================================ FILE: src/store.js ================================================ import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { user: null, isNewUser: true }, mutations: { SET_USER_DATA (state, userData) { localStorage.setItem('user', JSON.stringify(userData)) axios.defaults.headers.common['Authorization'] = `Bearer ${ userData.token }` state.user = userData }, LOGOUT () { localStorage.removeItem('user') location.reload() }, IS_NEW_USER (state, isNewUser) { state.isNewUser = isNewUser } }, actions: { register ({ commit }, credentials) { return axios .post('//localhost:3000/register', credentials) .then(({ data }) => { commit('SET_USER_DATA', data) }) }, login ({ commit }, credentials) { return axios .post('//localhost:3000/login', credentials) .then(({ data }) => { commit('SET_USER_DATA', data) }) }, logout ({ commit }) { commit('LOGOUT') }, isNewUser ({ commit }, isNewUser) { commit('IS_NEW_USER', isNewUser) } } }) ================================================ FILE: src/views/Authenticate.vue ================================================ ================================================ FILE: src/views/Dashboard.vue ================================================ ================================================ FILE: src/views/Home.vue ================================================ ================================================ FILE: vue.config.js ================================================ const path = require("path"); module.exports = { pluginOptions: { "style-resources-loader": { preProcessor: "scss", patterns: [path.resolve(__dirname, "./src/styles/global.scss")] } } };