diff --git a/README.md b/README.md index 10177c5..1704c67 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ First of all, set up your project by creating `.env` file with next content: ```env mongoUri = "" +jwtSecret = "" ``` Main available scripts in the project directory: @@ -59,6 +60,7 @@ module.exports = { NODE_ENV: "production", mongoUri: "" /*replace this*/, httpsRedirect: false /*true if enable*/, + jwtSecret: "", }, }, ], @@ -74,4 +76,5 @@ module.exports = { - NODE_ENV: production - mongoUri: YOUR MONGO URI - httpsRedirect: true + - jwtSecret: SECRET KEY - Click "Deploy branch" button diff --git a/app.js b/app.js index e05755a..70c9b20 100644 --- a/app.js +++ b/app.js @@ -10,22 +10,16 @@ const PORT = process.env.PORT || 5000 const mongoUri = process.env.mongoUri const httpsRedirect = process.env.httpsRedirect || false -//temporary backend url -const phpBaseUrl = 'https://php-server-notes.herokuapp.com/' - const app = express() app.use(express.json({ extended: true })) -//app.use('/api/auth', require('./routes/auth.routes')) +app.use('/api/auth', require('./routes/auth.routes')) +app.use('/api/server', require('./routes/phpserver.routes')) -app.post('/server', function (req, res) { - //console.log("backend redirect", req.url) - res.redirect(307, phpBaseUrl) -}) +if (httpsRedirect) app.use(httpToHttps) if (!devMode) { - if (httpsRedirect) app.use(httpToHttps) app.use('/', express.static(path.join(__dirname, 'client', 'build'))) app.get('*', (req, res) => { res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html')) @@ -38,16 +32,8 @@ if (!devMode) { async function start() { try { - if (mongoUri) { - await mongoose.connect(mongoUri, { - useNewUrlParser: true, - useUnifiedTopology: true, - useCreateIndex: true - }) - } else { - console.log("\n!!!NO MONGO URI!!!") - } - app.listen(PORT, () => logServerStart(PORT)) + connectMongo(mongoUri) + app.listen(PORT, logServerStart) } catch (e) { console.log('Server Error', e.message) process.exit(1) @@ -56,12 +42,25 @@ async function start() { start() -function logServerStart(PORT) { - dns.lookup(os.hostname(), (err, address, fam) => { - const [logN, bef, af] = devMode ? ['Express server', ' ', ':'] : ['React Notes App', '-', ''] - console.log(`\n${logN} has been started`) - console.log(`${bef} Local${af} http://localhost:${PORT}`) - console.log(`${bef} On Your Network${af} http://${address}:${PORT}`) +async function connectMongo(mongoUri) { + if (mongoUri) { + await mongoose.connect(mongoUri, { + useNewUrlParser: true, + useUnifiedTopology: true, + useCreateIndex: true + }) + } else { + console.log("\n!!!NO MONGO URI!!!") + } +} + +function logServerStart() { + dns.lookup(os.hostname(), (err, address) => { + const [logName, sBef, sAft] = devMode ? ['Express server', ' ', ':'] : ['React Notes App', '-', ''] + console.log(`\n${logName} has been started`) + console.log(`${sBef} Local${sAft} http://localhost:${PORT}`) + console.log(`${sBef} On Your Network${sAft} http://${address}:${PORT}`) + if (err) console.log(err) }) } diff --git a/client/package-lock.json b/client/package-lock.json index 8a1313b..47967ef 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1996,16 +1996,16 @@ } }, "@testing-library/dom": { - "version": "7.30.4", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.4.tgz", - "integrity": "sha512-GObDVMaI4ARrZEXaRy4moolNAxWPKvEYNV/fa6Uc2eAzR/t4otS6A7EhrntPBIQLeehL9DbVhscvvv7gd6hWqA==", + "version": "7.31.2", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", + "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^4.2.0", "aria-query": "^4.2.2", "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.4", + "dom-accessibility-api": "^0.5.6", "lz-string": "^1.4.4", "pretty-format": "^26.6.2" }, @@ -2056,9 +2056,9 @@ } }, "@testing-library/jest-dom": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.12.0.tgz", - "integrity": "sha512-N9Y82b2Z3j6wzIoAqajlKVF1Zt7sOH0pPee0sUHXHc5cv2Fdn23r+vpWm0MBBoGJtPOly5+Bdx1lnc3CD+A+ow==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.13.0.tgz", + "integrity": "sha512-+jXXTn8GjRnZkJfzG/tqK/2Q7dGlBInR412WE7Aml7CT3wdSpx5dMQC0HOwVQoZ3cNTmQUy8fCVGUV/Zhoyvcw==", "requires": { "@babel/runtime": "^7.9.2", "@types/testing-library__jest-dom": "^5.9.1", @@ -2140,9 +2140,9 @@ } }, "@testing-library/react": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.6.tgz", - "integrity": "sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ==", + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.7.tgz", + "integrity": "sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==", "requires": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^7.28.1" @@ -2269,9 +2269,9 @@ } }, "@types/jest": { - "version": "26.0.22", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.22.tgz", - "integrity": "sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw==", + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "requires": { "jest-diff": "^26.0.0", "pretty-format": "^26.0.0" @@ -2991,11 +2991,6 @@ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3691,9 +3686,9 @@ "integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==" }, "bootstrap-icons": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.4.1.tgz", - "integrity": "sha512-EcATaAGsRgyy4NtnwXlNzkgWttpb6PqcXCoLtZZKdZtAYJU/WYqoQFxuGFKAppOlf7NmKpvGtSsC/921H7LIjg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.5.0.tgz", + "integrity": "sha512-44feMc7DE1Ccpsas/1wioN8ewFJNquvi5FewA06wLnqct7CwMdGDVy41ieHaacogzDqLfG8nADIvMNp9e4bfbA==" }, "bowser": { "version": "1.9.4", @@ -5136,9 +5131,9 @@ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "requires": { "ip": "^1.1.0", "safe-buffer": "^5.0.1" @@ -5161,9 +5156,9 @@ } }, "dom-accessibility-api": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", - "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==" + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.6.tgz", + "integrity": "sha512-DplGLZd8L1lN64jlT27N9TVSESFR5STaEJvX+thCby7fuCHonfPpAlodYc3vuUYbDuDec5w8AMP7oCM5TWFsqw==" }, "dom-converter": { "version": "0.2.0", @@ -12823,9 +12818,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-markdown": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.1.tgz", - "integrity": "sha512-JNOIU+6xrG+eOwZu9UNZxDAc1bNBCpI8mueQNx5NwZWRbSrcD25FllhKHxyUkXhpdu3r/eg1hrLKCtCq9/uIrw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.2.tgz", + "integrity": "sha512-Et2AjXAsbmPP1nLQQRqmVgcqzfwcz8uQJ8VAdADs8Nk/aaUA0YeU9RDLuCtD+GwajCnm/+Iiu2KPmXzmD/M3vA==", "requires": { "@types/hast": "^2.0.0", "@types/unist": "^2.0.3", @@ -12838,7 +12833,8 @@ "space-separated-tokens": "^1.1.0", "style-to-object": "^0.3.0", "unified": "^9.0.0", - "unist-util-visit": "^2.0.0" + "unist-util-visit": "^2.0.0", + "vfile": "^4.0.0" }, "dependencies": { "react-is": { @@ -12947,9 +12943,9 @@ } }, "react-textarea-autosize": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz", - "integrity": "sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", "requires": { "@babel/runtime": "^7.10.2", "use-composed-ref": "^1.0.0", @@ -16671,11 +16667,18 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "requires": { "async-limiter": "~1.0.0" + }, + "dependencies": { + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + } } }, "yargs": { @@ -17115,9 +17118,9 @@ } }, "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" }, "xml-name-validator": { "version": "3.0.0", diff --git a/client/package.json b/client/package.json index 2fb7081..15de38f 100644 --- a/client/package.json +++ b/client/package.json @@ -3,18 +3,18 @@ "version": "0.1.0", "private": true, "dependencies": { - "@testing-library/jest-dom": "^5.12.0", - "@testing-library/react": "^11.2.6", + "@testing-library/jest-dom": "^5.13.0", + "@testing-library/react": "^11.2.7", "@testing-library/user-event": "^12.8.3", "bootstrap": "^4.6.0", - "bootstrap-icons": "^1.4.1", + "bootstrap-icons": "^1.5.0", "jquery": "^3.6.0", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-markdown": "^6.0.1", + "react-markdown": "^6.0.2", "react-scripts": "4.0.3", "react-stack-grid": "^0.7.1", - "react-textarea-autosize": "^8.3.2", + "react-textarea-autosize": "^8.3.3", "remark-gfm": "^1.0.0", "web-vitals": "^0.2.4", "workbox-background-sync": "^5.1.4", diff --git a/client/src/App.js b/client/src/App.js index f87951e..d988dd3 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,5 +1,5 @@ import React from 'react'; -import logo from './logo.svg'; +import logo from './Shared/Logo/logo.svg'; import './App.css'; import CardList from './Cards/CardList' import AddCard from './Cards/AddCard' diff --git a/client/src/Services/DataService.js b/client/src/Services/DataService.js index d202228..01fc03c 100644 --- a/client/src/Services/DataService.js +++ b/client/src/Services/DataService.js @@ -4,8 +4,7 @@ import Card, { checkCardsArr } from '../Cards/cardType/Card' export default function DataService() { //////////////////////////////////////////////////////////// var user = null - const nodeBackend = true - const baseUrl = nodeBackend ? '/server/' : 'http://php-server-notes.std-1033.ist.mospolytech.ru/' + const baseUrl = '/api/server/' //////////////////////////////////////////////////////////// function updDataServLogin(login) { @@ -74,7 +73,7 @@ export default function DataService() { function checkData(data) { //console.log('start check data') try { - if( data === null) console.log("null data"); + if (data === null) console.log("null data"); return data === null || data === [] || checkCardsArr(data) } catch { return false @@ -93,7 +92,7 @@ export default function DataService() { .then((d) => { let data = tryParce(d)//here we parce json //console.log("[DATA] from loadData(): ", data) - if(!data)console.log("empty data from server"); + if (!data) console.log("empty data from server"); if (!checkData(data)) { console.error("[loadData] Bad data format") console.log(data) @@ -121,10 +120,10 @@ export default function DataService() { ? Promise.reject(rej()) : loadData()) .then((d) => { - if(!data)console.log("empty data to post"); - if(!d)console.log("empty loaded to check"); + if (!data) console.log("empty data to post"); + if (!d) console.log("empty loaded to check"); let pDat = data === null ? (d || []) : data - if(!pDat)console.log("empty will be posted"); + if (!pDat) console.log("empty will be posted"); requestPostData(pDat).then(res, rej) }) .catch(rej) diff --git a/client/src/logo.svg b/client/src/Shared/Logo/logo.svg similarity index 100% rename from client/src/logo.svg rename to client/src/Shared/Logo/logo.svg diff --git a/middleware/auth.middleware.js b/middleware/auth.middleware.js new file mode 100644 index 0000000..9358fbb --- /dev/null +++ b/middleware/auth.middleware.js @@ -0,0 +1,24 @@ +const jwt = require('jsonwebtoken') +require('dotenv').config() + +module.exports = (req, res, next) => { + if (req.method === 'OPTIONS') { + return next() + } + + try { + + const token = req.headers.authorization.split(' ')[1] // "Bearer TOKEN" + + if (!token) { + return res.status(401).json({ message: 'Нет авторизации' }) + } + + const decoded = jwt.verify(token, process.env.jwtSecret) + req.user = decoded + next() + + } catch (e) { + res.status(401).json({ message: 'Нет авторизации' }) + } +} diff --git a/models/User.js b/models/User.js new file mode 100644 index 0000000..170b64b --- /dev/null +++ b/models/User.js @@ -0,0 +1,8 @@ +const {Schema, model, Types} = require('mongoose') + +const schema = new Schema({ + email: {type: String, required: true, unique: true}, + password: {type: String, required: true} +}) + +module.exports = model('User', schema) diff --git a/package-lock.json b/package-lock.json index 6a4f8e8..dff41f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,18 +14,18 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -91,18 +91,18 @@ } }, "@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "version": "3.6.17", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.17.tgz", + "integrity": "sha512-9hhgvYPdC5iHyyksPcKCu45gfaAIPQHKHGdvNXu4582DmOZX3wrUJIJPT40o4G1oTKPgpMMFqZglOTjhnYoF+A==", "requires": { "@types/bson": "*", "@types/node": "*" } }, "@types/node": { - "version": "14.14.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", - "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==" + "version": "15.12.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz", + "integrity": "sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -183,6 +183,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -260,6 +265,11 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" }, + "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=" + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -417,9 +427,9 @@ "dev": true }, "concurrently": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.0.2.tgz", - "integrity": "sha512-u+1Q0dJG5BidgUTpz9CU16yoHTt/oApFDQ3mbvHwSDgMjU7aGqy0q8ZQyaZyaNxdwRKTD872Ux3Twc6//sWA+Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.2.0.tgz", + "integrity": "sha512-v9I4Y3wFoXCSY2L73yYgwA9ESrQMpRn80jMcqMgHx720Hecz2GZAvTI6bREVST6lkddNypDKRN22qhK0X8Y00g==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -540,9 +550,9 @@ "dev": true }, "date-fns": { - "version": "2.21.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", - "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==", + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.22.1.tgz", + "integrity": "sha512-yUFPQjrxEmIsMqlHhAhmxkuH769baF21Kk+nZwZGyrMoyLA+LugaQtC0+Tqf9CBUUULWwUJt6Q5ySI3LJDDCGg==", "dev": true }, "debug": { @@ -599,9 +609,9 @@ } }, "dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, "duplexer3": { "version": "0.1.4", @@ -609,6 +619,14 @@ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", "dev": true }, + "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", @@ -708,6 +726,15 @@ "vary": "~1.1.2" } }, + "express-validator": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.11.1.tgz", + "integrity": "sha512-XAMdu1P6RESd8bvKtNdgNPsW+abkY6UQ2EVUqPpK6QVqieZKaLrN7W/zeFzDWZmgAy/RPEW8M4KYXMqQk6GmTA==", + "requires": { + "lodash": "^4.17.21", + "validator": "^13.5.2" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -924,9 +951,9 @@ } }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" @@ -1028,6 +1055,49 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "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==" + } + } + }, + "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" + } + }, "kareem": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.2.tgz", @@ -1060,8 +1130,42 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "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.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", @@ -1147,34 +1251,34 @@ "dev": true }, "mongodb": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.6.tgz", - "integrity": "sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", "requires": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", - "optional-require": "^1.0.2", + "optional-require": "^1.0.3", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" } }, "mongoose": { - "version": "5.12.5", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.5.tgz", - "integrity": "sha512-VVoqiELZcoI2HhHDuPpfN3qmExrtIeXSWNb1nihf4w1SJoWGXilU/g2cQgeeSMc2vAHSZd5Nv2sNPvbZHFw+pg==", + "version": "5.12.13", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.13.tgz", + "integrity": "sha512-QGn1FCzZ8Z+mMGVg8oR2kQw4NmhLloCHsw1NqKWg3Yr7WfPzkE4pe7s9P6o5pkYGsku17n9mqMHowne7EFK/zQ==", "requires": { "@types/mongodb": "^3.5.27", "bson": "^1.1.4", "kareem": "2.3.2", - "mongodb": "3.6.6", + "mongodb": "3.6.8", "mongoose-legacy-pluralize": "1.0.2", "mpath": "0.8.3", "mquery": "3.2.5", "ms": "2.1.2", "regexp-clone": "1.0.0", "safe-buffer": "5.2.1", - "sift": "7.0.1", + "sift": "13.5.2", "sliced": "1.0.1" }, "dependencies": { @@ -1372,9 +1476,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { @@ -1588,8 +1692,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-diff": { "version": "3.1.1", @@ -1667,9 +1770,9 @@ "dev": true }, "sift": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", - "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" + "version": "13.5.2", + "resolved": "https://registry.npmjs.org/sift/-/sift-13.5.2.tgz", + "integrity": "sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==" }, "signal-exit": { "version": "3.0.3", @@ -1724,9 +1827,9 @@ } }, "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "statuses": { @@ -1950,6 +2053,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "validator": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", + "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index a3d9ea3..851a3d8 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,15 @@ }, "homepage": "https://github.com/maxchistt/react-notes#readme", "dependencies": { - "dotenv": "^8.2.0", + "bcryptjs": "^2.4.3", + "dotenv": "^8.6.0", "express": "^4.17.1", - "mongoose": "^5.12.5" + "express-validator": "^6.11.1", + "jsonwebtoken": "^8.5.1", + "mongoose": "^5.12.13" }, "devDependencies": { - "concurrently": "^6.0.2", + "concurrently": "^6.2.0", "cross-env": "^7.0.3", "nodemon": "^2.0.7" } diff --git a/routes/auth.routes.js b/routes/auth.routes.js new file mode 100644 index 0000000..98c99c7 --- /dev/null +++ b/routes/auth.routes.js @@ -0,0 +1,94 @@ +const {Router} = require('express') +const bcrypt = require('bcryptjs') +require('dotenv').config() +const jwt = require('jsonwebtoken') +const {check, validationResult} = require('express-validator') +const User = require('../models/User') +const router = Router() + +// /api/auth/register +router.post( + '/register', + [ + check('email', 'Некорректный email').isEmail(), + check('password', 'Минимальная длина пароля 6 символов') + .isLength({ min: 6 }) + ], + async (req, res) => { + try { + const errors = validationResult(req) + + if (!errors.isEmpty()) { + return res.status(400).json({ + errors: errors.array(), + message: 'Некорректный данные при регистрации' + }) + } + + const {email, password} = req.body + + const candidate = await User.findOne({ email }) + + if (candidate) { + return res.status(400).json({ message: 'Такой пользователь уже существует' }) + } + + const hashedPassword = await bcrypt.hash(password, 12) + const user = new User({ email, password: hashedPassword }) + + await user.save() + + res.status(201).json({ message: 'Пользователь создан' }) + + } catch (e) { + res.status(500).json({ message: 'Что-то пошло не так, попробуйте снова' }) + } +}) + +// /api/auth/login +router.post( + '/login', + [ + check('email', 'Введите корректный email').normalizeEmail().isEmail(), + check('password', 'Введите пароль').exists() + ], + async (req, res) => { + try { + const errors = validationResult(req) + + if (!errors.isEmpty()) { + return res.status(400).json({ + errors: errors.array(), + message: 'Некорректный данные при входе в систему' + }) + } + + const {email, password} = req.body + + const user = await User.findOne({ email }) + + if (!user) { + return res.status(400).json({ message: 'Пользователь не найден' }) + } + + const isMatch = await bcrypt.compare(password, user.password) + + if (!isMatch) { + return res.status(400).json({ message: 'Неверный пароль, попробуйте снова' }) + } + + const token = jwt.sign( + { userId: user.id }, + process.env.jwtSecret, + { expiresIn: '1h' } + ) + + res.json({ token, userId: user.id }) + + } catch (e) { + res.status(500).json({ message: 'Что-то пошло не так, попробуйте снова' }) + } +}) + + +module.exports = router diff --git a/routes/phpserver.routes.js b/routes/phpserver.routes.js new file mode 100644 index 0000000..f9b6b81 --- /dev/null +++ b/routes/phpserver.routes.js @@ -0,0 +1,18 @@ +const { Router } = require('express') +//const auth = require('../middleware/auth.middleware') +const router = Router() + +//temporary backend url +const phpBaseUrl = 'https://php-server-notes.herokuapp.com/' + +//auth not used +router.post('/', /*auth,*/ async (req, res) => { + try { + //console.log("backend redirect", req.url) + res.redirect(307, phpBaseUrl) + } catch (e) { + res.status(500).json({ message: 'Что-то пошло не так, попробуйте снова' }) + } +}) + +module.exports = router