banner-data
This commit is contained in:
parent
bd6a846043
commit
2e159814e4
@ -10,8 +10,10 @@
|
|||||||
Пример:
|
Пример:
|
||||||
|
|
||||||
```.env
|
```.env
|
||||||
PORT=4343
|
RED_CODER_BH_PORT=8045
|
||||||
SESSION_SECRET="secret string"
|
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. Установка зависимостей
|
### 2. Установка зависимостей
|
||||||
|
@ -5,7 +5,7 @@ volumes:
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
mongoDb:
|
mongoDb:
|
||||||
image: mongo:latest
|
image: mongo:5.0.7
|
||||||
volumes:
|
volumes:
|
||||||
- red-coder_volume:/data/db
|
- red-coder_volume:/data/db
|
||||||
restart: always
|
restart: always
|
||||||
|
4
index.d.ts
vendored
Normal file
4
index.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
declare module '*.json' {
|
||||||
|
const data: any;
|
||||||
|
export default data;
|
||||||
|
}
|
@ -27,8 +27,15 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/cookie-session": "^2.0.44",
|
||||||
|
"cookie-session": "^2.0.0",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
"express": "^4.17.3",
|
"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": {
|
"devDependencies": {
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
|
3
src/config.ts
Normal file
3
src/config.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { config } from 'dotenv';
|
||||||
|
|
||||||
|
config();
|
16
src/main.ts
16
src/main.ts
@ -1,22 +1,18 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { config } from 'dotenv';
|
import cookieSession from 'cookie-session';
|
||||||
|
|
||||||
|
import './config';
|
||||||
import { errorHandle } from './utils/error-handling';
|
import { errorHandle } from './utils/error-handling';
|
||||||
|
import { router } from './routes';
|
||||||
config();
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
const port = process.env.RED_CODER_BH_PORT;
|
const port = process.env.RED_CODER_BH_PORT;
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
app.use(express.json());
|
||||||
res.send('hello')
|
app.use(cookieSession({ secret: process.env.COOKIE_SESSION }));
|
||||||
})
|
|
||||||
|
|
||||||
app.get('/error', (req, res) => {
|
|
||||||
throw new Error('some mistake')
|
|
||||||
})
|
|
||||||
|
|
||||||
|
app.use(router);
|
||||||
|
|
||||||
app.use(errorHandle);
|
app.use(errorHandle);
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
76
src/routes/auth.ts
Normal file
76
src/routes/auth.ts
Normal file
@ -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);
|
||||||
|
});
|
||||||
|
});
|
19
src/routes/banner/data.json
Normal file
19
src/routes/banner/data.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"title": "Подсказка на сегодня",
|
||||||
|
"body": "Подберите задачки под свой уровень сложности, решите её и наращивайте навык",
|
||||||
|
"icon": "allGood"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Подсказка на завтра",
|
||||||
|
"body": "Не забудь сутра выпить кофе",
|
||||||
|
"icon": "coding"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Подсказка на вчера",
|
||||||
|
"body": "Забыл сутра выпить кофе?",
|
||||||
|
"icon": "askingQuestion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
9
src/routes/banner/index.ts
Normal file
9
src/routes/banner/index.ts
Normal file
@ -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)
|
||||||
|
})
|
9
src/routes/index.ts
Normal file
9
src/routes/index.ts
Normal file
@ -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);
|
@ -33,7 +33,7 @@
|
|||||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
// "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. */
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
// "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 `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||||
|
|
||||||
/* JavaScript Support */
|
/* JavaScript Support */
|
||||||
|
Loading…
Reference in New Issue
Block a user