diff --git a/.env b/.env new file mode 100644 index 0000000..481f7da --- /dev/null +++ b/.env @@ -0,0 +1 @@ +TOKEN_KEY=5frv12e4few3r \ No newline at end of file diff --git a/package.json b/package.json index deab2b9..a351a3f 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "@ijl/cli": "^5.1.0", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", + "dotenv": "^16.4.5", "emoji-mart": "^5.6.0", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", diff --git a/src/backend/api.js b/src/backend/api.js index dcb0606..8006f71 100644 --- a/src/backend/api.js +++ b/src/backend/api.js @@ -10,10 +10,13 @@ export const BASE_API_URL = DEV + getConfigValue("enterfront.api"); // fetch(`${BASE_API_URL}/books/list`) export async function post(path, body) { + const token = localStorage.getItem('token'); + const res = await fetch(`${BASE_API_URL}${path}`, { method: "POST", headers: { "Content-Type": "application/json", + "Authorization": token ? `Bearer ${token}` : undefined }, body: JSON.stringify(body) }); @@ -32,8 +35,13 @@ export async function post(path, body) { } export async function get(path){ + const token = localStorage.getItem('token'); + const res = await fetch(`${BASE_API_URL}${path}`, { - method: "GET" + method: "GET", + headers: { + "Authorization": token ? `Bearer ${token}` : undefined + } }); if (res.status === 200) { diff --git a/src/pages/Account.jsx b/src/pages/Account.jsx index c6d51c8..35a698f 100644 --- a/src/pages/Account.jsx +++ b/src/pages/Account.jsx @@ -1,10 +1,11 @@ import React, {useEffect, useState} from "react"; import AccountButtons from "../components/account/AccountButtons.jsx"; import userIcon from "../../images/user.svg"; -import {get} from "../backend/api"; +import {get, post} from "../backend/api"; import {displayMessage} from "../backend/notifications/notifications"; import {MessageType} from "../backend/notifications/message"; import HelloItem from "../components/account/HelloItem.jsx"; +import { URLs } from "../__data__/urls"; const Account = () => { const exitHandler = () => { @@ -14,12 +15,27 @@ const Account = () => { localStorage.setItem("message", "Exited successfully!"); window.location.href = "/"; } - const changeNameHandler = () => {} - const changePassHandler = () => {} const [nickname, setNickname] = useState(""); const [id, setId] = useState(""); + async function changeNameHandler () { + // ... + + const {ok, data} = await post('/change/nickname', {id: id, newNickname: "New Name"}); + + if (!ok) { + displayMessage(data.message, MessageType.ERROR); + } else { + localStorage.setItem("message", "Name was changed"); + window.location.href = URLs.account.url; + } + } + + async function changePassHandler (){ + // ... + } + async function getUser() { const username = localStorage.getItem("username"); if (!username) { diff --git a/stubs/api/auth/index.js b/stubs/api/auth/index.js index 0d9731f..485aab8 100644 --- a/stubs/api/auth/index.js +++ b/stubs/api/auth/index.js @@ -1,30 +1,16 @@ const authRouter = require('express').Router(); -// For cryptography -// const bcrypt = require('bcrypt'); - // For creating tokens const jwt = require('jsonwebtoken'); -const TOKEN_KEY = "5frv12e4few3r" + +require('dotenv').config(); +const TOKEN_KEY = process.env.TOKEN_KEY; module.exports = authRouter; -// Read already defined users (pseudo-DB) -const users = require('./users.json'); +const { users, getUserFromDB } = require('../db'); -const getUserFromDB = (userID) => { - if (!userID) {return false;} - - // Accessing 'DB' - const user = users.find((user) => user.id === userID); - - if (user) { - return user; - } else { - return false; - } -} // Get a user by its id authRouter.get('/:id', (req, res) => { diff --git a/stubs/api/books/book-list.json b/stubs/api/books/book-list.json deleted file mode 100644 index 1f6d483..0000000 --- a/stubs/api/books/book-list.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "content": { - - }, - "totalElement": 0 -} \ No newline at end of file diff --git a/stubs/api/books/book.json b/stubs/api/books/book.json deleted file mode 100644 index 4c24b18..0000000 --- a/stubs/api/books/book.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "1", - "name": "Book name", - "description": "Interesting book description" -} \ No newline at end of file diff --git a/stubs/api/books/index.js b/stubs/api/books/index.js deleted file mode 100644 index 254ad06..0000000 --- a/stubs/api/books/index.js +++ /dev/null @@ -1,36 +0,0 @@ -const booksRouter = require('express').Router(); - -module.exports = booksRouter; - -const books = [] - -booksRouter.get('/list', (req, res) => { - res.send(require('./book-list.json')) -}) - -booksRouter.post('/', (req, res) => { - // body() can be used because of dev server - console.log(req.body) - books.push({ - name: req.body.name, - }) - - res.send({ - status: 200 - }) -}) - - -booksRouter.get('/:id', (req, res) => { - console.log(req.params); - - res.send(require('./book.json')); - - // res.status(404).send() -}) - -booksRouter.delete('/:id', (req, res) => { - res.status(201).send({ - status: 'ok' - }) -}) diff --git a/stubs/api/change/index.js b/stubs/api/change/index.js new file mode 100644 index 0000000..959e935 --- /dev/null +++ b/stubs/api/change/index.js @@ -0,0 +1,46 @@ +const changeRouter = require('express').Router(); + +module.exports = changeRouter; + +const { users, getUserFromDB } = require('../db'); + +const jwt = require("jsonwebtoken"); + + +changeRouter.post('/nickname', (req, res) => { + const { id, newNickname } = req.body; + console.log("Request nickname in /change:", id); + + const user = getUserFromDB(id); + + // Invalid identification + if (!user) { + res.status(401).send({message: 'Invalid credentials (id)'}); + } + + // Delete the old one + const index = users.findIndex(item => item.id === id); + if (index !== -1) { + users.splice(index, 1); // Remove the old user + } + + // Insert updated + users.push({ + "nickname": newNickname, + "password": user.password, + "id": user.id + }); + + res.status(200).send({}); +}); + +changeRouter.post('/password', (req, res) => { + const { id, newPassword } = req.body; + // ... +}); + +changeRouter.delete('/:id', (req, res) => { + const { id } = req.params; + // ... +}); + diff --git a/stubs/api/db.js b/stubs/api/db.js new file mode 100644 index 0000000..0f5038b --- /dev/null +++ b/stubs/api/db.js @@ -0,0 +1,17 @@ +// Read already defined users (pseudo-DB) +const users = require('./auth/users.json'); + +const getUserFromDB = (userID) => { + if (!userID) {return false;} + + // Accessing 'DB' + const user = users.find((user) => user.id === userID); + + if (user) { + return user; + } else { + return false; + } +} + +module.exports = {users, getUserFromDB} diff --git a/stubs/api/index.js b/stubs/api/index.js index 9e2ef60..3fd0cda 100644 --- a/stubs/api/index.js +++ b/stubs/api/index.js @@ -1,9 +1,10 @@ -const booksRouter = require("./books"); +const changeRouter = require("./change"); const authRouter = require("./auth"); const router = require('express').Router(); const delay = require('./middlewares/delay'); +const verify = require('./middlewares/verify'); module.exports = router; @@ -11,3 +12,4 @@ module.exports = router; // router.use('/books', delay, booksRouter); router.use('/auth', authRouter); +router.use('/change', verify, changeRouter); diff --git a/stubs/api/middlewares/verify.js b/stubs/api/middlewares/verify.js new file mode 100644 index 0000000..bcc653d --- /dev/null +++ b/stubs/api/middlewares/verify.js @@ -0,0 +1,23 @@ +const jwt = require('jsonwebtoken'); + +require('dotenv').config(); +const TOKEN_KEY = process.env.TOKEN_KEY; + +function verifyToken(req, res, next) { + const token = req.headers['authorization']?.split(' ')[1]; + + if (!token) { + return res.status(403).send({ message: 'No token provided' }); + } + + // Verify token + jwt.verify(token, TOKEN_KEY, (err, decoded) => { + if (err) { + return res.status(401).send({ message: 'Unauthorized' }); + } + + next(); // Proceed to the next middleware or route + }); +} + +module.exports = verifyToken;