forked from bro-students/multy-stub
		
	Merge pull request 'Cats backend routes' (#30) from cats into master
Reviewed-on: bro-students/multy-stub#30
This commit is contained in:
		
						commit
						6015bce32f
					
				
							
								
								
									
										147
									
								
								server/routers/epja-2024-1/cats/admin/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								server/routers/epja-2024-1/cats/admin/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
const adminRouter = require('express').Router();
 | 
			
		||||
const fs = require('fs');
 | 
			
		||||
const path = require('path');
 | 
			
		||||
const { TOKEN } = require('../const');
 | 
			
		||||
require('dotenv').config();
 | 
			
		||||
 | 
			
		||||
const dataFilePath = path.join(__dirname, '../data.json');
 | 
			
		||||
let data = require('../data.json');
 | 
			
		||||
 | 
			
		||||
const verifyToken = (req, res, next) => {
 | 
			
		||||
    const token = req.headers['authorization'];
 | 
			
		||||
    if (token === TOKEN) {
 | 
			
		||||
        next();
 | 
			
		||||
    } else {
 | 
			
		||||
        res.status(403).send({ 'status': 'Failed', 'data': 'Invalid token' });
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const saveData = (data) => {
 | 
			
		||||
    fs.writeFileSync(dataFilePath, JSON.stringify(data, null, 2), 'utf-8');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/nickname', verifyToken, (req, res) => {
 | 
			
		||||
    const { name, colored } = req.body;
 | 
			
		||||
    if (!name || !colored) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Nickname is required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.nickname = { name, colored };
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Nickname updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/tech-stack', verifyToken, (req, res) => {
 | 
			
		||||
    const { techStack } = req.body;
 | 
			
		||||
    if (!techStack || !Array.isArray(techStack)) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Valid tech stack is required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.techStack = techStack;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Tech stack updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/city', verifyToken, (req, res) => {
 | 
			
		||||
    const { city } = req.body;
 | 
			
		||||
    if (!city) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'City is required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isValid = typeof city === 'object' && 'name' in city && 'href' in city;
 | 
			
		||||
 | 
			
		||||
    if (!isValid) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'City must contain href and name' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.city = city;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'City updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/github-repo', verifyToken, (req, res) => {
 | 
			
		||||
    const { github } = req.body;
 | 
			
		||||
    if (!github) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Github is required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isValid = typeof github === 'object' && 'author' in github && 'repo' in github;
 | 
			
		||||
 | 
			
		||||
    if (!isValid) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Github must contain author and repo' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.githubRepo = github;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Github updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/nav-links', verifyToken, (req, res) => {
 | 
			
		||||
    const { navLinks } = req.body;
 | 
			
		||||
    if (!navLinks || !Array.isArray(navLinks)) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Valid navLinks are required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isValid = navLinks.every(link =>
 | 
			
		||||
        link && typeof link === 'object' && 'href' in link && 'title' in link
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (!isValid) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Each navLink must contain href and title' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.navLinks = navLinks;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Navigation links updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/links', verifyToken, (req, res) => {
 | 
			
		||||
    const { links } = req.body;
 | 
			
		||||
    if (!links || !Array.isArray(links)) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Valid links are required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const isValid = links.every(link =>
 | 
			
		||||
        link && typeof link === 'object' && 'href' in link && 'title' in link
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (!isValid) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Each link must contain href and title' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.links = links;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Links updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
adminRouter.post('/edit/projects', verifyToken, (req, res) => {
 | 
			
		||||
    const { projects } = req.body;
 | 
			
		||||
    if (!projects) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'Projects are required' });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const projectFields = ['id', 'title', 'description', 'link', 'techStack', 'image'];
 | 
			
		||||
 | 
			
		||||
    const isValidProject = (project) => {
 | 
			
		||||
        return projectFields.every(field => field && field in project);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const allProjectsValid = projects.every(project => isValidProject(project));
 | 
			
		||||
 | 
			
		||||
    if (!allProjectsValid) {
 | 
			
		||||
        return res.status(400).send({ 'status': 'Failed', 'data': 'All projects must contain ' + projectFields.join(", ") });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.projects = projects;
 | 
			
		||||
    saveData(data);
 | 
			
		||||
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': 'Projects updated successfully' });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
module.exports = adminRouter;
 | 
			
		||||
							
								
								
									
										16
									
								
								server/routers/epja-2024-1/cats/auth/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								server/routers/epja-2024-1/cats/auth/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
const authRouter = require('express').Router();
 | 
			
		||||
const { TOKEN } = require('../const');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = authRouter;
 | 
			
		||||
 | 
			
		||||
authRouter.post('/login', (req, res) => {
 | 
			
		||||
    const { email, password } = req.body;
 | 
			
		||||
    console.log(`Login with email=${email} and password=${password}`);
 | 
			
		||||
 | 
			
		||||
    if (email === 'admin@admin.admin' && password === 'admin') {
 | 
			
		||||
        res.status(200).send({ 'status': 'OK', 'data': `${TOKEN}` });
 | 
			
		||||
    } else {
 | 
			
		||||
        res.status(401).send({ 'status': 'Failed!', 'data': 'Invalid email or password' });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										3
									
								
								server/routers/epja-2024-1/cats/const.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								server/routers/epja-2024-1/cats/const.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
const TOKEN = "ASDFGHJKLLKJHGFDSDFGHJKJHGF";
 | 
			
		||||
 | 
			
		||||
module.exports = { TOKEN }
 | 
			
		||||
							
								
								
									
										118
									
								
								server/routers/epja-2024-1/cats/data.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								server/routers/epja-2024-1/cats/data.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,118 @@
 | 
			
		||||
{
 | 
			
		||||
  "nickname": {
 | 
			
		||||
    "name": "supercool",
 | 
			
		||||
    "colored": "nickname"
 | 
			
		||||
  },
 | 
			
		||||
  "techStack": [
 | 
			
		||||
    "React",
 | 
			
		||||
    "Next.js",
 | 
			
		||||
    "Svelte",
 | 
			
		||||
    "SvelteKit",
 | 
			
		||||
    "HTML",
 | 
			
		||||
    "CSS",
 | 
			
		||||
    "JavaScript",
 | 
			
		||||
    "TypeScript",
 | 
			
		||||
    "TailwindCSS",
 | 
			
		||||
    "Styled-Components",
 | 
			
		||||
    "Framer-Motion",
 | 
			
		||||
    "shadcn-ui",
 | 
			
		||||
    "Ant-Design",
 | 
			
		||||
    "ESLint",
 | 
			
		||||
    "Prettier",
 | 
			
		||||
    "husky",
 | 
			
		||||
    "lint-staged",
 | 
			
		||||
    "Redux",
 | 
			
		||||
    "RTK Query",
 | 
			
		||||
    "Tanstack Query",
 | 
			
		||||
    "Python",
 | 
			
		||||
    "FastApi",
 | 
			
		||||
    "Flask",
 | 
			
		||||
    "SQLite",
 | 
			
		||||
    "PostgreSQL",
 | 
			
		||||
    "MongoDB",
 | 
			
		||||
    "SQLAlchemy",
 | 
			
		||||
    "Alembic",
 | 
			
		||||
    "PyPy",
 | 
			
		||||
    "poetry",
 | 
			
		||||
    "pylint",
 | 
			
		||||
    "GitHub Actions",
 | 
			
		||||
    "GitLab CI/CD",
 | 
			
		||||
    "Docker",
 | 
			
		||||
    "Git"
 | 
			
		||||
  ],
 | 
			
		||||
  "githubRepo": {
 | 
			
		||||
    "author": "MishaBlin",
 | 
			
		||||
    "repo": "EPJA_portfolio_app"
 | 
			
		||||
  },
 | 
			
		||||
  "city": {
 | 
			
		||||
    "name": "Innopolis",
 | 
			
		||||
    "href": "https://ru.wikipedia.org/wiki/Иннополис"
 | 
			
		||||
  },
 | 
			
		||||
  "navLinks": [
 | 
			
		||||
    {
 | 
			
		||||
      "href": "#about",
 | 
			
		||||
      "title": "About"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "href": "#projects",
 | 
			
		||||
      "title": "Projects"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "links": [
 | 
			
		||||
    {
 | 
			
		||||
      "href": "mailto:svyatoslavsvyatkin@yandex.ru",
 | 
			
		||||
      "title": "Mail"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "href": "https://t.me/dmhd6219",
 | 
			
		||||
      "title": "Telegram"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "href": "https://github.com/dmhd6219",
 | 
			
		||||
      "title": "GitHub"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "href": "https://last.fm/user/dmhd",
 | 
			
		||||
      "title": "LastFm"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "href": "https://pay.cloudtips.ru/p/02da9349",
 | 
			
		||||
      "title": "Buy me a coffee"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "projects": [
 | 
			
		||||
    {
 | 
			
		||||
      "title": "Elasticsearch",
 | 
			
		||||
      "description": "Elasticsearch is a distributed search and analytics engine, scalable data store and vector database optimized for speed and relevance on production-scale workloads.",
 | 
			
		||||
      "link": "https://github.com/elastic/elasticsearch",
 | 
			
		||||
      "techStack": [
 | 
			
		||||
        "Java",
 | 
			
		||||
        "Groovy"
 | 
			
		||||
      ],
 | 
			
		||||
      "image": "https://datascientest.com/en/files/2023/04/Elasticsearch.jpg",
 | 
			
		||||
      "id": "elasticsearch"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "title": "React-native",
 | 
			
		||||
      "description": "React Native brings React's declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access to the native platform.",
 | 
			
		||||
      "link": "https://github.com/facebook/react-native",
 | 
			
		||||
      "techStack": [
 | 
			
		||||
        "C++",
 | 
			
		||||
        "Javascript",
 | 
			
		||||
        "Kotlin"
 | 
			
		||||
      ],
 | 
			
		||||
      "image": "https://www.simplilearn.com/ice9/free_resources_article_thumb/React_Native_Tutorial.jpg",
 | 
			
		||||
      "id": "react-native"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "title": "Zarr",
 | 
			
		||||
      "description": "Zarr is a Python package providing an implementation of compressed, chunked, N-dimensional arrays, designed for use in parallel computing. See the documentation for more information.",
 | 
			
		||||
      "link": "https://github.com/zarr-developers/zarr-python",
 | 
			
		||||
      "techStack": [
 | 
			
		||||
        "Python"
 | 
			
		||||
      ],
 | 
			
		||||
      "image": "https://raw.githubusercontent.com/zarr-developers/community/main/logos/logo2.png",
 | 
			
		||||
      "id": "zarr"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								server/routers/epja-2024-1/cats/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								server/routers/epja-2024-1/cats/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
const authRouter = require('./auth');
 | 
			
		||||
const adminRouter = require('./admin');
 | 
			
		||||
const rootRouter = require('./root');
 | 
			
		||||
 | 
			
		||||
const router = require('express').Router();
 | 
			
		||||
 | 
			
		||||
module.exports = router;
 | 
			
		||||
 | 
			
		||||
router.use(`/auth`, authRouter);
 | 
			
		||||
router.use(`/admin`, adminRouter);
 | 
			
		||||
router.use(`/`, rootRouter);
 | 
			
		||||
							
								
								
									
										44
									
								
								server/routers/epja-2024-1/cats/root/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								server/routers/epja-2024-1/cats/root/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
const rootRouter = require('express').Router();
 | 
			
		||||
const data = require('../data.json');
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/nickname', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.nickname });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/tech-stack', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.techStack });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/github-repo', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.githubRepo });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/city', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.city });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/nav-links', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.navLinks });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/links', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.links });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/projects', (req, res) => {
 | 
			
		||||
    res.status(200).send({ 'status': 'OK', 'data': data.projects });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
rootRouter.get('/get/projects/:id', (req, res) => {
 | 
			
		||||
    const { id } = req.params;
 | 
			
		||||
    const project = data.projects.find(p => p.id === id);
 | 
			
		||||
    
 | 
			
		||||
    if (project) {
 | 
			
		||||
        res.status(200).send({ status: 'OK', data: project });
 | 
			
		||||
    } else {
 | 
			
		||||
        res.status(404).send({ status: 'NOT_FOUND', message: 'Project not found' });
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
module.exports = rootRouter;
 | 
			
		||||
@ -4,4 +4,6 @@ const router = express.Router()
 | 
			
		||||
 | 
			
		||||
router.use('/enterfront', require('./enterfront/index'))
 | 
			
		||||
 | 
			
		||||
router.use('/cats', require('./cats/index'))
 | 
			
		||||
 | 
			
		||||
module.exports = router
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user