Skip to content

Instantly share code, notes, and snippets.

@luizcalaca
Created July 10, 2023 13:31
Show Gist options
  • Save luizcalaca/87f7352214627c8bee5f1c26c86123ba to your computer and use it in GitHub Desktop.
Save luizcalaca/87f7352214627c8bee5f1c26c86123ba to your computer and use it in GitHub Desktop.
API + Node.js + Express.js + Token + business rules
'use strict';
const lodash = require('lodash');
const {v4} = require('uuid');
const express = require('express');
const app = express();
app.use(express.json());
// In-memory database
const users = [];
const articles = [];
function findUserByLogin(login) {
return users.find(user => user.login === login);
}
function authenticate(req, res, next) {
const token = req.headers['authentication-header'];
const user = users.find(user => user.tokens.includes(token));
if (!user) {
res.sendStatus(401);
} else {
req.user = user;
next();
}
}
// POST /api/user
app.post('/api/user', (req, res) => {
const { user_id, login, password } = req.body;
if (!user_id || !login || !password)
return res.sendStatus(400);
if (findUserByLogin(login))
return res.sendStatus(409);
const newUser = {
user_id,
login,
password,
tokens: []
};
users.push(newUser);
return res.sendStatus(201);
});
// POST /api/authenticate
app.post('/api/authenticate', (req, res) => {
const { login, password } = req.body;
if (!login || !password)
return res.sendStatus(400);
const user = findUserByLogin(login);
if (!user)
return res.sendStatus(404);
if (user.password === password) {
const token = v4();
user.tokens.push(token);
return res.status(200).json({ "token": token });
} else {
return res.sendStatus(401);
}
});
// POST /api/logout
app.post('/api/logout', authenticate, (req, res) => {
const { user } = req;
const token = req.headers['authentication-header'];
if(lodash.isEmpty(token))
return res.sendStatus(401);
if (user.tokens.includes(token)) {
user.tokens = user.tokens.filter(t => t == token);
return res.sendStatus(200);
}else{
return res.sendStatus(401);
}
});
// POST /api/articles
app.post('/api/articles', authenticate, (req, res) => {
if (Object.keys(req.body).length === 0)
return res.status(400).json();
const token = req.headers['authentication-header'];
const { user } = req;
const { article_id, title, content, visibility } = req.body;
if (user.tokens.includes(token)) {
const newArticle = {
article_id,
title,
content,
visibility,
user_id: user.user_id
};
articles.push(newArticle);
return res.sendStatus(201);
} else {
return res.sendStatus(401);
}
});
// GET /api/articles
app.get('/api/articles', (req, res) => {
const token = req.headers['authentication-header'];
const user = users.find(user => user.tokens.includes(token));
const visibleArticles = [];
if (user) {
visibleArticles.push(...articles.filter(article => (
article.visibility === 'public' ||
article.visibility === 'logged_in' ||
(article.visibility === 'private' && article.user_id === user.user_id)
)));
} else {
visibleArticles.push(...articles.filter(article => article.visibility === 'public'));
}
return res.status(200).json(visibleArticles);
});
app.use((req, res, next) => {
res.sendStatus(404);
});
exports.default = app.listen(process.env.HTTP_PORT || 3500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment