mirror of https://github.com/xfarrow/blink
Following API best practices
This commit is contained in:
parent
4f53ef7561
commit
ae14f04949
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,5 @@
|
|||
# APIs
|
||||
|
||||
## Programming language
|
||||
The Blink APIs are currently written in NodeJS only.
|
||||
|
||||
## Prerequisites
|
||||
* PostgreSQL;
|
||||
* NodeJS.
|
||||
|
@ -16,3 +13,8 @@ In order to deploy the Blink APIs, follow these steps:
|
|||
You can test the APIs in two ways:
|
||||
* Open `BlinkApiUsageExample.json` with Insomnia or Bruno in order to have the collection of APIs already configured and ready to be seen in action;
|
||||
* Run `npm test` in `./nodejs` to run a suite of automated tests.
|
||||
|
||||
## For Developers
|
||||
The current implementation of the Blink APIs is written in NodeJS. Feel free to develop them in any other
|
||||
programming language (you can paste the folder here) but make sure to make them compatible with one another
|
||||
and please follow the API design [best practices](https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design)
|
||||
|
|
|
@ -38,8 +38,9 @@ async function isPersonOrganizationAdministrator(personId, organizationId) {
|
|||
*/
|
||||
async function addOrganizationAdministrator(personId, organizationId, requester) {
|
||||
|
||||
const isPersonAdmin = await organization_admin_model.isPersonAdmin(requester, organizationId);
|
||||
if (isPersonAdmin) {
|
||||
const isRequesterAdmin = await isPersonOrganizationAdministrator(requester, organizationId);
|
||||
const isPersonAdmin = await isPersonOrganizationAdministrator(personId, organizationId);
|
||||
if (isRequesterAdmin && !isPersonAdmin) {
|
||||
await knex('OrganizationAdministrator')
|
||||
.insert({
|
||||
id_person: personId,
|
||||
|
|
|
@ -25,14 +25,14 @@ const jwtUtils = require('../utils/middleware_utils');
|
|||
*/
|
||||
async function addOrganizationAdmin(req, res) {
|
||||
// Ensure that the required fields are present before proceeding
|
||||
if (!req.body.organization_id || !req.body.person_id) {
|
||||
if (!req.params.id || !req.body.person_id) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid request'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const success = await organizationAdminModel.addOrganizationAdministrator(req.body.person_id, req.body.organization_id, req.jwt.person_id);
|
||||
const success = await organizationAdminModel.addOrganizationAdministrator(req.body.person_id, req.params.id, req.jwt.person_id);
|
||||
if (success) {
|
||||
return res.status(200).json({
|
||||
success: true
|
||||
|
@ -60,14 +60,14 @@ async function addOrganizationAdmin(req, res) {
|
|||
*/
|
||||
async function removeOrganizationAdmin(req, res) {
|
||||
// Ensure that the required fields are present before proceeding
|
||||
if (!req.body.organization_id) {
|
||||
if (!req.params.organizationId) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid request'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await organizationAdminModel.removeOrganizationAdmin(req.jwt.person_id, req.body.organization_id);
|
||||
await organizationAdminModel.removeOrganizationAdmin(req.jwt.person_id, req.params.organizationId);
|
||||
return res.status(200).json({
|
||||
success: true
|
||||
});
|
||||
|
@ -81,8 +81,8 @@ async function removeOrganizationAdmin(req, res) {
|
|||
|
||||
const protectedRoutes = express.Router();
|
||||
protectedRoutes.use(jwtUtils.verifyToken);
|
||||
protectedRoutes.post('/organization/admin', addOrganizationAdmin);
|
||||
protectedRoutes.delete('/organization/admin', removeOrganizationAdmin);
|
||||
protectedRoutes.post('/organizations/:id/admins', addOrganizationAdmin);
|
||||
protectedRoutes.delete('/organizations/:organizationId/admins/me', removeOrganizationAdmin);
|
||||
|
||||
module.exports = {
|
||||
protectedRoutes
|
||||
|
|
|
@ -25,20 +25,25 @@ const jwtUtils = require('../utils/middleware_utils');
|
|||
*/
|
||||
async function createOrganizationPost(req, res) {
|
||||
// Ensure that the required fields are present before proceeding
|
||||
if (!req.body.organization_id || !req.body.content) {
|
||||
if (!req.params.idOrganization || !req.body.content) {
|
||||
return res.status(400).json({
|
||||
error: 'Invalid request'
|
||||
});
|
||||
}
|
||||
|
||||
const organization = organizationPostModel.createOrganizationPost(
|
||||
req.body.organization_id,
|
||||
const organizationPost = organizationPostModel.createOrganizationPost(
|
||||
req.params.idOrganization,
|
||||
req.body.content,
|
||||
req.jwt.person_id);
|
||||
|
||||
try {
|
||||
const insertedOrganization = await organizationPostModel.insertOrganizationPost(organization);
|
||||
const insertedOrganization = await organizationPostModel.insertOrganizationPost(organizationPost);
|
||||
if(!!insertedOrganization){
|
||||
return res.status(200).json(insertedOrganization);
|
||||
}
|
||||
return res.status(401).json({
|
||||
error: 'Forbidden'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error in function ${createOrganizationPost.name}: ${error}`);
|
||||
return res.status(500).json({
|
||||
|
@ -78,8 +83,8 @@ async function deleteOrganizationPost(req, res) {
|
|||
|
||||
const protectedRoutes = express.Router();
|
||||
protectedRoutes.use(jwtUtils.verifyToken);
|
||||
protectedRoutes.post('/organization/post', createOrganizationPost);
|
||||
protectedRoutes.delete('/organization/post/:id', deleteOrganizationPost);
|
||||
protectedRoutes.post('/organizations/:idOrganization/posts', createOrganizationPost);
|
||||
protectedRoutes.delete('/organizations/posts/:id', deleteOrganizationPost);
|
||||
|
||||
// Exporting a function
|
||||
// means making a JavaScript function defined in one
|
||||
|
|
|
@ -147,13 +147,13 @@ async function getOrganization(req, res) {
|
|||
}
|
||||
|
||||
const publicRoutes = express.Router();
|
||||
publicRoutes.get('/organization/:id', getOrganization);
|
||||
publicRoutes.get('/organizations/:id', getOrganization);
|
||||
|
||||
const protectedRoutes = express.Router();
|
||||
protectedRoutes.use(jwtUtils.verifyToken);
|
||||
protectedRoutes.post('/organization', createOrganization);
|
||||
protectedRoutes.put('/organization/:id', updateOrganization);
|
||||
protectedRoutes.delete('/organization/:id', deleteOrganization);
|
||||
protectedRoutes.post('/organizations', createOrganization);
|
||||
protectedRoutes.put('/organizations/:id', updateOrganization);
|
||||
protectedRoutes.delete('/organizations/:id', deleteOrganization);
|
||||
|
||||
module.exports = {
|
||||
publicRoutes,
|
||||
|
|
|
@ -92,7 +92,7 @@ async function registerPerson(req, res) {
|
|||
*
|
||||
* @returns The token
|
||||
*/
|
||||
async function login(req, res) {
|
||||
async function createTokenByEmailAndPassword(req, res) {
|
||||
// Ensure that the required fields are present before proceeding
|
||||
if (!req.body.email || !req.body.password) {
|
||||
return res.status(400).json({
|
||||
|
@ -113,7 +113,7 @@ async function login(req, res) {
|
|||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error in function ${login.name}: ${error}`);
|
||||
console.error(`Error in function ${createTokenByEmailAndPassword.name}: ${error}`);
|
||||
return res.status(500).json({
|
||||
error: 'Internal server error'
|
||||
});
|
||||
|
@ -312,16 +312,16 @@ async function confirmActivation(req, res) {
|
|||
}
|
||||
|
||||
const publicRoutes = express.Router(); // Routes not requiring token
|
||||
publicRoutes.post('/register', registerPerson);
|
||||
publicRoutes.post('/login', login);
|
||||
publicRoutes.get('/person/:id/details', getPerson);
|
||||
publicRoutes.get('/person/activation', confirmActivation);
|
||||
publicRoutes.post('/persons', registerPerson);
|
||||
publicRoutes.post('/persons/me/token', createTokenByEmailAndPassword);
|
||||
publicRoutes.get('/persons/:id/details', getPerson);
|
||||
publicRoutes.get('/persons/me/activation', confirmActivation);
|
||||
|
||||
const protectedRoutes = express.Router(); // Routes requiring token
|
||||
protectedRoutes.use(jwtUtils.verifyToken);
|
||||
protectedRoutes.get('/person/myself', getMyself);
|
||||
protectedRoutes.put('/person', updatePerson);
|
||||
protectedRoutes.delete('/person', deletePerson);
|
||||
protectedRoutes.get('/persons/me', getMyself);
|
||||
protectedRoutes.put('/persons/me', updatePerson);
|
||||
protectedRoutes.delete('/persons/me', deletePerson);
|
||||
|
||||
// Exporting a function
|
||||
// means making a JavaScript function defined in one
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
alert('Please fill in all fields');
|
||||
return;
|
||||
}
|
||||
const response = await fetch(`${API_URL}/login`, {
|
||||
const response = await fetch(`${API_URL}/persons/me/token`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
email: email,
|
||||
|
@ -59,7 +59,7 @@
|
|||
if (response.ok) {
|
||||
console.log(`Login was successful. Token is ${data.token}`);
|
||||
document.cookie = `token=${data.token};`;
|
||||
window.location.href = 'userprofile.html?id=myself';
|
||||
window.location.href = 'userprofile.html?id=me';
|
||||
} else {
|
||||
alert(data.error);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
}),
|
||||
};
|
||||
|
||||
fetch(`${API_URL}/register`, options)
|
||||
fetch(`${API_URL}/persons`, options)
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
alert("Congratulations! You've successfully registered to Blink." +
|
||||
|
|
|
@ -58,21 +58,21 @@
|
|||
let response;
|
||||
|
||||
// Retrieving the logged in user's profile
|
||||
if (!idToDisplay || idToDisplay === 'myself') {
|
||||
if (!idToDisplay || idToDisplay === 'me') {
|
||||
document.getElementById('editBadge').style.display = 'block'; // show edit button
|
||||
const token = getCookie('token');
|
||||
// Check whether the token exists
|
||||
if (!token) {
|
||||
window.location.href = 'login.html';
|
||||
}
|
||||
response = await fetch(`${API_URL}/person/myself`, {
|
||||
response = await fetch(`${API_URL}/persons/me`, {
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
"authorization": token
|
||||
}
|
||||
});
|
||||
} else {
|
||||
response = await fetch(`${API_URL}/person/${idToDisplay}/details`, {
|
||||
response = await fetch(`${API_URL}/persons/${idToDisplay}/details`, {
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8",
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue