diff --git a/README.md b/README.md index 6a25252..214d854 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,10 @@ Пример: ```.env -PORT=4343 -SESSION_SECRET="secret string" +RED_CODER_BH_PORT=8045 +SESSION_SECRET="asdas a dasd sad as dasd as" +COOKIE_SESSION="sdfsfdjkbhjvav dbw fsfnnsdonan dlansln dlasnldnsa da" +JWT_SECRET_STRING="wow wow it is a secret shhhhhhh....." ``` ### 2. Установка зависимостей diff --git a/docker-compose.yaml b/docker-compose.yaml index 64f3fd1..68580c4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,7 +5,7 @@ volumes: services: mongoDb: - image: mongo:latest + image: mongo:5.0.7 volumes: - red-coder_volume:/data/db restart: always diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..5c7cdf7 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const data: any; + export default data; +} diff --git a/package.json b/package.json index e2f3e98..135f63c 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,15 @@ "author": "", "license": "MIT", "dependencies": { + "@types/cookie-session": "^2.0.44", + "cookie-session": "^2.0.0", + "dotenv": "^16.0.0", "express": "^4.17.3", - "dotenv": "^16.0.0" + "express-jwt": "^6.1.1", + "jsonwebtoken": "^8.5.1", + "jwt-middleware": "^0.3.0", + "pbkdf2-password": "^1.2.1", + "uuid": "^8.3.2" }, "devDependencies": { "@types/express": "^4.17.13", diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..8902e23 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,3 @@ +import { config } from 'dotenv'; + +config(); diff --git a/src/main.ts b/src/main.ts index 47b6661..083f944 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,22 +1,18 @@ import express from 'express'; -import { config } from 'dotenv'; +import cookieSession from 'cookie-session'; +import './config'; import { errorHandle } from './utils/error-handling'; - -config(); +import { router } from './routes'; const app = express(); const port = process.env.RED_CODER_BH_PORT; -app.get('/', (req, res) => { - res.send('hello') -}) - -app.get('/error', (req, res) => { - throw new Error('some mistake') -}) +app.use(express.json()); +app.use(cookieSession({ secret: process.env.COOKIE_SESSION })); +app.use(router); app.use(errorHandle); app.listen(port, () => { diff --git a/src/routes/auth.ts b/src/routes/auth.ts new file mode 100644 index 0000000..6c6a864 --- /dev/null +++ b/src/routes/auth.ts @@ -0,0 +1,76 @@ +import { Router } from 'express'; +import pbkdf2Password from 'pbkdf2-password'; +import { v4 as uuid } from 'uuid'; +import jwt from 'jsonwebtoken'; +import jwtMiddleware from 'express-jwt'; + +const makeHash = pbkdf2Password(); + +export const authRouter = Router(); + +const requiredFields = (fields: string[]) => (req, res, next) => { + for (const fieldName of fields) { + if (!req.body[fieldName]) { + throw new Error(`Field ${fieldName} does\'t set`) + } + } + + next(); +}; + +const users: any[] = []; + + +authRouter.get('/users', jwtMiddleware({ secret: process.env.JWT_SECRET_STRING, algorithms: ['HS256'] }), (req, res) => { + res.send(users); +}); + +authRouter.post('/sign-in', requiredFields(['password', 'login']), (req, res) => { + const { password, login } = req.body; + + const user = users.find(u => u.login === login); + + if (!user) { + res.status(400).send({ error: 'Login or password does\'t match' }); + return; + } + + makeHash({ password, salt: user.salt }, (err, pass, salt, hash) => { + if (err) throw err; + + if (user.hash === hash) { + const { hash: _hash, salt: _salt, ...cleanUser } = user + + req.session.user = cleanUser; + const token = jwt.sign(cleanUser, process.env.JWT_SECRET_STRING, { + + }); + + return res.send({ token, user: cleanUser }) + } + + res.status(400).send({ error: 'Login or password does\'t match' }); + }); +}); + +authRouter.post('/sign-up', requiredFields(['password', 'login', 'email']), (req, res, next) => { + const { password, login, ...rest } = req.body; + + makeHash({ password }, function (err, pass, salt, hash) { + if (err) throw err; + + const newUser = { + id: uuid(), + ...rest, + login, + salt, + hash + } + + users.push(newUser); + + const { hash: _hash, salt: _salt, ...cleanUser } = newUser + + res.send(cleanUser); + }); +}); diff --git a/src/routes/banner/data.json b/src/routes/banner/data.json new file mode 100644 index 0000000..05931f3 --- /dev/null +++ b/src/routes/banner/data.json @@ -0,0 +1,19 @@ +{ + "data": [ + { + "title": "Подсказка на сегодня", + "body": "Подберите задачки под свой уровень сложности, решите её и наращивайте навык", + "icon": "allGood" + }, + { + "title": "Подсказка на завтра", + "body": "Не забудь сутра выпить кофе", + "icon": "coding" + }, + { + "title": "Подсказка на вчера", + "body": "Забыл сутра выпить кофе?", + "icon": "askingQuestion" + } + ] +} \ No newline at end of file diff --git a/src/routes/banner/index.ts b/src/routes/banner/index.ts new file mode 100644 index 0000000..7448970 --- /dev/null +++ b/src/routes/banner/index.ts @@ -0,0 +1,9 @@ +import { Router } from 'express'; + +import BannerData from './data.json'; + +export const bannerRouter = Router(); + +bannerRouter.get('/banner-data', (req, res) => { + res.send(BannerData) +}) diff --git a/src/routes/index.ts b/src/routes/index.ts new file mode 100644 index 0000000..e2f4c88 --- /dev/null +++ b/src/routes/index.ts @@ -0,0 +1,9 @@ +import { Router } from 'express'; + +import { authRouter } from './auth'; +import { bannerRouter } from './banner'; + +export const router = Router(); + +router.use(bannerRouter); +router.use('/auth', authRouter); diff --git a/tsconfig.json b/tsconfig.json index bed29d3..f351095 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,7 +33,7 @@ // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "resolveJsonModule": true, /* Enable importing .json files */ + "resolveJsonModule": true, /* Enable importing .json files */ // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */