From d7033efc496932bd58cc8a7bda5b2112f4f41d46 Mon Sep 17 00:00:00 2001 From: Miltiadis Skondras Date: Sun, 28 Nov 2021 19:52:25 +0000 Subject: [PATCH] Added Jsdoc documentation for the code --- controllers/auth.js | 8 +- docs/jsdocs/controllers_auth.js.html | 62 + docs/jsdocs/controllers_validation.js.html | 4 +- docs/jsdocs/helpers_database.js.html | 4 +- docs/jsdocs/index.html | 4 +- docs/jsdocs/models_applications.js.html | 157 +++ docs/jsdocs/models_users.js.html | 142 +++ docs/jsdocs/module-controllers_auth.html | 85 ++ .../jsdocs/module-controllers_validation.html | 4 +- ...le-helpers_database-DatabaseException.html | 4 +- docs/jsdocs/module-helpers_database.html | 4 +- docs/jsdocs/module-models_applications.html | 922 +++++++++++++ docs/jsdocs/module-models_users.html | 1081 ++++++++++++++++ .../module-permissions_applications.html | 496 +++++++ docs/jsdocs/module-permissions_users.html | 815 ++++++++++++ docs/jsdocs/module-routes_applications.html | 976 ++++++++++++++ docs/jsdocs/module-routes_users.html | 1136 +++++++++++++++++ docs/jsdocs/module-strategies_basic.html | 359 ++++++ docs/jsdocs/permissions_applications.js.html | 122 ++ docs/jsdocs/permissions_users.js.html | 166 +++ docs/jsdocs/routes_applications.js.html | 205 +++ docs/jsdocs/routes_users.js.html | 203 +++ docs/jsdocs/strategies_basic.js.html | 103 ++ models/applications.js | 46 +- models/users.js | 54 +- permissions/applications.js | 27 +- permissions/users.js | 44 + routes/applications.js | 59 +- routes/users.js | 63 +- schemas/user.json | 4 +- strategies/basic.js | 15 + 31 files changed, 7330 insertions(+), 44 deletions(-) create mode 100644 docs/jsdocs/controllers_auth.js.html create mode 100644 docs/jsdocs/models_applications.js.html create mode 100644 docs/jsdocs/models_users.js.html create mode 100644 docs/jsdocs/module-controllers_auth.html create mode 100644 docs/jsdocs/module-models_applications.html create mode 100644 docs/jsdocs/module-models_users.html create mode 100644 docs/jsdocs/module-permissions_applications.html create mode 100644 docs/jsdocs/module-permissions_users.html create mode 100644 docs/jsdocs/module-routes_applications.html create mode 100644 docs/jsdocs/module-routes_users.html create mode 100644 docs/jsdocs/module-strategies_basic.html create mode 100644 docs/jsdocs/permissions_applications.js.html create mode 100644 docs/jsdocs/permissions_users.js.html create mode 100644 docs/jsdocs/routes_applications.js.html create mode 100644 docs/jsdocs/routes_users.js.html create mode 100644 docs/jsdocs/strategies_basic.js.html diff --git a/controllers/auth.js b/controllers/auth.js index 58bf722..77ec70f 100644 --- a/controllers/auth.js +++ b/controllers/auth.js @@ -1,6 +1,8 @@ -// Set up passport and its authentications strategies. -// Importing this module in a route gives a middleware handler that can be used -// to protect downstream handlers by rejecting unauthenticated requests. +/** + * @module controllers/auth + * @author Miltos Skondras + * + */ const passport = require('koa-passport'); const basicAuth = require('../strategies/basic'); diff --git a/docs/jsdocs/controllers_auth.js.html b/docs/jsdocs/controllers_auth.js.html new file mode 100644 index 0000000..5ff8c95 --- /dev/null +++ b/docs/jsdocs/controllers_auth.js.html @@ -0,0 +1,62 @@ + + + + + JSDoc: Source: controllers/auth.js + + + + + + + + + + +
+ +

Source: controllers/auth.js

+ + + + + + +
+
+
/**
+ * @module controllers/auth
+ * @author Miltos Skondras
+ * 
+ */
+
+const passport = require('koa-passport');
+const basicAuth = require('../strategies/basic');
+
+passport.use(basicAuth);
+
+module.exports = passport.authenticate(['basic'], {session:false});
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/controllers_validation.js.html b/docs/jsdocs/controllers_validation.js.html index b4d66bf..365dddd 100644 --- a/docs/jsdocs/controllers_validation.js.html +++ b/docs/jsdocs/controllers_validation.js.html @@ -93,13 +93,13 @@ exports.validateApplication = makeKoaValidator(appSchema, 'application');
diff --git a/docs/jsdocs/helpers_database.js.html b/docs/jsdocs/helpers_database.js.html index 62754a8..354a7fb 100644 --- a/docs/jsdocs/helpers_database.js.html +++ b/docs/jsdocs/helpers_database.js.html @@ -86,13 +86,13 @@ function DatabaseException(message, code, id) {
diff --git a/docs/jsdocs/index.html b/docs/jsdocs/index.html index d148d4e..4716adb 100644 --- a/docs/jsdocs/index.html +++ b/docs/jsdocs/index.html @@ -50,13 +50,13 @@
diff --git a/docs/jsdocs/models_applications.js.html b/docs/jsdocs/models_applications.js.html new file mode 100644 index 0000000..1f69b41 --- /dev/null +++ b/docs/jsdocs/models_applications.js.html @@ -0,0 +1,157 @@ + + + + + JSDoc: Source: models/applications.js + + + + + + + + + + +
+ +

Source: models/applications.js

+ + + + + + +
+
+
/**
+ * Database module for the application modification
+ * 
+ * @module models/applications
+ * @author Miltos Skondras
+ */
+
+const db = require('../helpers/database');
+
+/**
+ * getAll
+ * 
+ * @description Returns all applications
+ * @return {object} Objects containing application data
+ */
+exports.getAll = async function getAll (page, limit, order, direction) {
+  const offset = (page - 1) * limit;
+  let query;
+  if (direction === 'DESC') {
+    query = "SELECT * FROM applications ORDER BY ?? DESC LIMIT ? OFFSET ?;";
+  } else {
+    query = "SELECT * FROM applications ORDER BY ?? ASC LIMIT ? OFFSET ?;";    
+  }
+  const values = [order, parseInt(limit), parseInt(offset)];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+/**
+ * getById
+ * 
+ * @description Returns a single application based on its ID
+ * @param {number} id - The ID of the application
+ * @return {object} Object containing information on that specific application
+ */
+exports.getById = async function getById (id) {
+  const query = "SELECT * FROM applications WHERE ID = ?;";
+  const values = [id];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+/**
+ * add
+ * 
+ * @description Adds an application to the database
+ * @param {object} application - Application data in JSON format
+ * @return {object} Response from database
+ */
+exports.add = async function add (application) {
+  const query = "INSERT INTO applications SET ?";
+  const data = await db.run_query(query, application);
+  return data;
+}
+
+/**
+ * delById
+ * 
+ * @description Deletes an application from the database based on its ID
+ * @param {number} id - The ID of the application that will be deleted
+ * @return {object} Response from database
+ */
+exports.delById = async function delById (id) {
+  const query = "DELETE FROM appications WHERE ID = ?;";
+  const values = [id];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+/**
+ * update
+ * 
+ * @description Updates an application from the database based on its ID
+ * @param {number} application - The ID of the application that will be updated
+ * @return {object} Response from database
+ */
+exports.update = async function update (appication) {
+  const query = "UPDATE applications SET ? WHERE ID = ?;";
+  const values = [appication, appication.ID];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+// get all applications with a pending status
+exports.getByPendingStatus = async function getByPendingStatus (applicationStatus) {
+  const query = "SELECT * FROM applications WHERE applicationStatus = 'pending';";
+  const values = [applicationStatus];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+// get all applications with an accepted status
+exports.getByAcceptedStatus = async function getByAcceptedStatus (currentStatus) {
+  const query = "SELECT * FROM applications WHERE applicationStatus = 'accepted';";
+  const values = [applicationStatus];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+// get all applications with a rejected status
+exports.getByStatusRejected = async function getByRejectedStatus (applicationStatus) {
+  const query = "SELECT * FROM applications WHERE currentStatus = 'rejected';";
+  const values = [applicationStatus];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/models_users.js.html b/docs/jsdocs/models_users.js.html new file mode 100644 index 0000000..feb890a --- /dev/null +++ b/docs/jsdocs/models_users.js.html @@ -0,0 +1,142 @@ + + + + + JSDoc: Source: models/users.js + + + + + + + + + + +
+ +

Source: models/users.js

+ + + + + + +
+
+
/**
+ * Database module for the user modification
+ * 
+ * @module models/users
+ * @author Miltos Skondras
+ */
+
+const db = require('../helpers/database');
+const bcrypt = require('bcrypt');
+
+/**
+ * getById
+ * 
+ * @description Returns a single user based on their ID
+ * @param {object} id - The ID of the user
+ * @return {object} Object containing information on that specific user
+ */
+exports.getById = async function getById (id) {
+  const query = "SELECT * FROM users WHERE ID = ?;";
+  const values = [id];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+/**
+ * findByUsername
+ * 
+ * @description Returns a single user based on their username
+ * @param {string} username - The username of the user
+ * @return {object }Object containing information on that specific user
+ */
+exports.findByUsername = async function getByUsername(username) {
+  const query = "SELECT * FROM users WHERE username = ?;";
+  const user = await db.run_query(query, username);
+  return user;
+}
+
+/**
+ * getAll
+ * 
+ * @description Returns all users
+ * @return {object} Objects containing user data
+ */
+exports.getAll = async function getAll (page, limit, order) {
+  const query = "SELECT * FROM users;";
+  const data = await db.run_query(query);
+  return data;
+}
+
+/**
+ * add
+ * 
+ * @description Adds a user to the database
+ * @param {object} user - User data in JSON format
+ * @return {object} Response from database
+ */
+exports.add = async function add (user) {
+  const query = "INSERT INTO users SET ?";
+  const password = user.password;
+  const hash = bcrypt.hashSync(password, 10);
+  user.password = hash;
+  const data = await db.run_query(query, user);
+  return data;
+}
+
+/**
+ * delById
+ * 
+ * @description Deletes a user from the database based on its ID
+ * @param {number} id - The ID of the user that will be deleted
+ * @return {object} Response from database
+ */
+exports.delById = async function delById (id) {
+  const query = "DELETE FROM users WHERE ID = ?;";
+  const values = [id];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+/**
+ * update
+ * 
+ * @description Updates a user from the database based on its ID
+ * @param {number} user - The ID of the user that will be updated
+ * @return {object} Response from database
+ */
+exports.update = async function update (user) {
+  const query = "UPDATE users SET ? WHERE ID = ?;";
+  const values = [user, user.ID];
+  const data = await db.run_query(query, values);
+  return data;
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/module-controllers_auth.html b/docs/jsdocs/module-controllers_auth.html new file mode 100644 index 0000000..94d67c6 --- /dev/null +++ b/docs/jsdocs/module-controllers_auth.html @@ -0,0 +1,85 @@ + + + + + JSDoc: Module: controllers/auth + + + + + + + + + + +
+ +

Module: controllers/auth

+ + + + + + +
+ +
+ + + +
+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-controllers_validation.html b/docs/jsdocs/module-controllers_validation.html index 46c89b5..8c517f3 100644 --- a/docs/jsdocs/module-controllers_validation.html +++ b/docs/jsdocs/module-controllers_validation.html @@ -478,13 +478,13 @@
diff --git a/docs/jsdocs/module-helpers_database-DatabaseException.html b/docs/jsdocs/module-helpers_database-DatabaseException.html index fe4cf87..8044995 100644 --- a/docs/jsdocs/module-helpers_database-DatabaseException.html +++ b/docs/jsdocs/module-helpers_database-DatabaseException.html @@ -254,13 +254,13 @@
diff --git a/docs/jsdocs/module-helpers_database.html b/docs/jsdocs/module-helpers_database.html index 0a4c8b1..b40f87b 100644 --- a/docs/jsdocs/module-helpers_database.html +++ b/docs/jsdocs/module-helpers_database.html @@ -392,13 +392,13 @@
diff --git a/docs/jsdocs/module-models_applications.html b/docs/jsdocs/module-models_applications.html new file mode 100644 index 0000000..4fbfd4d --- /dev/null +++ b/docs/jsdocs/module-models_applications.html @@ -0,0 +1,922 @@ + + + + + JSDoc: Module: models/applications + + + + + + + + + + +
+ +

Module: models/applications

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Database module for the application modification
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) add(application) → {object}

+ + + + + + +
+ Adds an application to the database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
application + + +object + + + + Application data in JSON format
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) delById(id) → {object}

+ + + + + + +
+ Deletes an application from the database based on its ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
id + + +number + + + + The ID of the application that will be deleted
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) getAll() → {object}

+ + + + + + +
+ Returns all applications +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Objects containing application data +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) getById(id) → {object}

+ + + + + + +
+ Returns a single application based on its ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
id + + +number + + + + The ID of the application
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Object containing information on that specific application +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) update(application) → {object}

+ + + + + + +
+ Updates an application from the database based on its ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
application + + +number + + + + The ID of the application that will be updated
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-models_users.html b/docs/jsdocs/module-models_users.html new file mode 100644 index 0000000..4048091 --- /dev/null +++ b/docs/jsdocs/module-models_users.html @@ -0,0 +1,1081 @@ + + + + + JSDoc: Module: models/users + + + + + + + + + + +
+ +

Module: models/users

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Database module for the user modification
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) add(user) → {object}

+ + + + + + +
+ Adds a user to the database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
user + + +object + + + + User data in JSON format
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) delById(id) → {object}

+ + + + + + +
+ Deletes a user from the database based on its ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
id + + +number + + + + The ID of the user that will be deleted
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) findByUsername(username) → {object}

+ + + + + + +
+ Returns a single user based on their username +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
username + + +string + + + + The username of the user
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Object containing information on that specific user +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) getAll() → {object}

+ + + + + + +
+ Returns all users +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Objects containing user data +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) getById(id) → {object}

+ + + + + + +
+ Returns a single user based on their ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
id + + +object + + + + The ID of the user
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Object containing information on that specific user +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +

(static) update(user) → {object}

+ + + + + + +
+ Updates a user from the database based on its ID +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
user + + +number + + + + The ID of the user that will be updated
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Response from database +
+ + + +
+
+ Type +
+
+ +object + + +
+
+ + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-permissions_applications.html b/docs/jsdocs/module-permissions_applications.html new file mode 100644 index 0000000..1e6f3f2 --- /dev/null +++ b/docs/jsdocs/module-permissions_applications.html @@ -0,0 +1,496 @@ + + + + + JSDoc: Module: permissions/applications + + + + + + + + + + +
+ +

Module: permissions/applications

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Permissions module for the applications
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) delete(requester, data)

+ + + + + + +
+ Checks whether the user has permission to delete the application +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
data + + +object + + + + The data of the application
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) update(requester, data)

+ + + + + + +
+ Checks whether the user has permission to update the application +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
data + + +object + + + + The data of the application
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-permissions_users.html b/docs/jsdocs/module-permissions_users.html new file mode 100644 index 0000000..3ef98ca --- /dev/null +++ b/docs/jsdocs/module-permissions_users.html @@ -0,0 +1,815 @@ + + + + + JSDoc: Module: permissions/users + + + + + + + + + + +
+ +

Module: permissions/users

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Permissions module for the users
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(static) delete(requester, data)

+ + + + + + +
+ Checks whether the user has permission to delete a user +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
data + + +object + + + + The data of the user
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) read(requester, data)

+ + + + + + +
+ Checks whether the user has permission to read user data +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
data + + +object + + + + The data of the application
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(static) readAll(requester) → {boolean}

+ + + + + + +
+ Checks whether user has permission to get all the users +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + +
Returns:
+ + +
+ Boolean response on whether or not the user has permission to complete this action +
+ + + +
+
+ Type +
+
+ +boolean + + +
+
+ + + + + + + + + + + + + +

(static) update(requester, data)

+ + + + + + +
+ Checks whether the user has permission to update the user +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
requester + + +object + + + + The user object of the person requesting
data + + +object + + + + The data of the user
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-routes_applications.html b/docs/jsdocs/module-routes_applications.html new file mode 100644 index 0000000..87b6ed9 --- /dev/null +++ b/docs/jsdocs/module-routes_applications.html @@ -0,0 +1,976 @@ + + + + + JSDoc: Module: routes/applications + + + + + + + + + + +
+ +

Module: routes/applications

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Routes for the application
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, inner) createApplication(ctx, next)

+ + + + + + +
+ Creates a new application in the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) deleteApplication(ctx, next)

+ + + + + + +
+ Deletes application from the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) getAll(ctx, next)

+ + + + + + +
+ Returns all applications from the DataBase. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) getById(ctx, next)

+ + + + + + +
+ getById +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) updateApplication(ctx, next)

+ + + + + + +
+ Updates application in the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-routes_users.html b/docs/jsdocs/module-routes_users.html new file mode 100644 index 0000000..21d0130 --- /dev/null +++ b/docs/jsdocs/module-routes_users.html @@ -0,0 +1,1136 @@ + + + + + JSDoc: Module: routes/users + + + + + + + + + + +
+ +

Module: routes/users

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
Routes for users
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, inner) createUser(ctx, next)

+ + + + + + +
+ Creates a new user in the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) deleteUser(ctx, next)

+ + + + + + +
+ Deletes a user from the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) getAll(ctx, next)

+ + + + + + +
+ Returns all users from the DataBase. +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) getById(ctx, next)

+ + + + + + +
+ getById +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) login(ctx, next)

+ + + + + + +
+ Returns user information +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

(async, inner) updateUser(ctx, next)

+ + + + + + +
+ Updates a user in the Database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
ctx + + +object + + + + Context object of HTTP Request
next + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/module-strategies_basic.html b/docs/jsdocs/module-strategies_basic.html new file mode 100644 index 0000000..84a70cf --- /dev/null +++ b/docs/jsdocs/module-strategies_basic.html @@ -0,0 +1,359 @@ + + + + + JSDoc: Module: strategies/basic + + + + + + + + + + +
+ +

Module: strategies/basic

+ + + + + + +
+ +
+ + + + + +
+ +
+
+ + +
User authentication strategy
+ + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Author:
+
+
    +
  • Miltos Skondras
  • +
+
+ + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +

Methods

+ + + + + + + +

(async, inner) checkUserAndPass(username, password, done)

+ + + + + + +
+ Authenticates user by checking their info in the database +
+ + + + + + + + + +
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescription
username + + +string + + + + Username of user
password + + +string + + + + Password of user
done + + +function + + + + Callback
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + +
+ + + + + + + \ No newline at end of file diff --git a/docs/jsdocs/permissions_applications.js.html b/docs/jsdocs/permissions_applications.js.html new file mode 100644 index 0000000..bc0ea1f --- /dev/null +++ b/docs/jsdocs/permissions_applications.js.html @@ -0,0 +1,122 @@ + + + + + JSDoc: Source: permissions/applications.js + + + + + + + + + + +
+ +

Source: permissions/applications.js

+ + + + + + +
+
+
/** 
+ * Permissions module for the applications
+ * 
+ * @module permissions/applications
+ * @author Miltos Skondras
+ */
+
+const AccessControl = require('role-acl');
+const ac = new AccessControl();
+
+
+ac
+  .grant('user')
+  .condition({Fn:'EQUALS', args: {'requester':'$.owner'}})
+  .execute('update')
+  .on('application');
+
+ac
+  .grant('user')
+  .execute('delete')
+  .on('application');
+
+ac
+  .grant('admin')
+  .execute('update')
+  .on('application');
+
+
+ac
+  .grant('admin')
+  .execute('delete')
+  .on('application');
+
+
+/**
+ * update
+ * 
+ * @description Checks whether the user has permission to update the application
+ * 
+ * @param {object} requester - The user object of the person requesting
+ * @param {object} data - The data of the application
+ * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.update = (requester, data) => {
+    console.log(requester)
+    console.log(data)
+  return ac
+    .can(requester.role)
+    .context({requester:requester.ID, owner:data.authorID})
+    .execute('update')
+    .sync()
+    .on('application');
+}
+
+/**
+ * delete
+ * 
+ * @description Checks whether the user has permission to delete the application
+ * 
+ * @param {object} requester - The user object of the person requesting
+ * @param {object} data - The data of the application
+ * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.delete = (requester) => {
+  return ac
+    .can(requester.role)
+    .execute('delete')
+    .sync()
+    .on('application');
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/permissions_users.js.html b/docs/jsdocs/permissions_users.js.html new file mode 100644 index 0000000..e2b3667 --- /dev/null +++ b/docs/jsdocs/permissions_users.js.html @@ -0,0 +1,166 @@ + + + + + JSDoc: Source: permissions/users.js + + + + + + + + + + +
+ +

Source: permissions/users.js

+ + + + + + +
+
+
/** 
+ * Permissions module for the users
+ * 
+ * @module permissions/users
+ * @author Miltos Skondras
+ */
+
+const AccessControl = require('role-acl');
+const ac = new AccessControl();
+
+// controls for CRUD operations on user records
+ac
+  .grant('user')
+  .condition({Fn:'EQUALS', args: {'requester':'$.owner'}})
+  .execute('read')
+  .on('user', ['*', '!password', '!passwordSalt']);
+
+ac
+  .grant('user')
+  .condition({Fn:'EQUALS', args: {'requester':'$.owner'}})
+  .execute('update')
+  .on('user', ['firstName', 'lastName', 'about', 'password', 'email', 'avatarURL']);
+
+ac
+  .grant('admin')
+  .execute('read')
+  .on('user');
+
+ac
+  .grant('admin')
+  .execute('read')
+  .on('users');
+
+ac
+  .grant('admin')
+  .execute('update')
+  .on('user');
+
+ac
+  .grant('admin')
+  .condition({Fn:'NOT_EQUALS', args: {'requester':'$.owner'}})
+  .execute('delete')
+  .on('user');
+
+/**
+ * readAll
+ * @description Checks whether user has permission to get all the users
+ *
+ * @param {object} requester - The user object of the person requesting
+ * @returns {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.readAll = (requester) => {
+  return ac
+    .can(requester.role)
+    .execute('read')
+    .sync()
+    .on('users');
+}
+
+/**
+ * read
+ * 
+ * @description Checks whether the user has permission to read user data
+ * 
+ * @param {object} requester - The user object of the person requesting
+ * @param {object} data - The data of the application
+ * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.read = (requester, data) => {
+  return ac
+    .can(requester.role)
+    .context({requester:requester.ID, owner:data.ID})
+    .execute('read')
+    .sync()
+    .on('user');
+}
+
+/**
+ * update
+ * 
+ * @description Checks whether the user has permission to update the user
+ * 
+ * @param {object} requester - The user object of the person requesting
+ * @param {object} data - The data of the user
+ * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.update = (requester, data) => {
+  return ac
+    .can(requester.role)
+    .context({requester:requester.ID, owner:data.ID})
+    .execute('update')
+    .sync()
+    .on('user');
+}
+
+/**
+ * delete
+ * 
+ * @description Checks whether the user has permission to delete a user
+ * 
+ * @param {object} requester - The user object of the person requesting
+ * @param {object} data - The data of the user
+ * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action
+ */
+
+exports.delete = (requester, data) => {
+  return ac
+    .can(requester.role)
+    .context({requester:requester.ID, owner:data.ID})
+    .execute('delete')
+    .sync()
+    .on('user');
+}
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/routes_applications.js.html b/docs/jsdocs/routes_applications.js.html new file mode 100644 index 0000000..8b3ea60 --- /dev/null +++ b/docs/jsdocs/routes_applications.js.html @@ -0,0 +1,205 @@ + + + + + JSDoc: Source: routes/applications.js + + + + + + + + + + +
+ +

Source: routes/applications.js

+ + + + + + +
+
+
/**
+ * Routes for the application
+ * 
+ * @module routes/applications
+ * @author Miltos Skondras
+ */
+
+const Router = require('koa-router');
+const bodyParser = require('koa-bodyparser');
+
+const auth = require('../controllers/auth');
+const applications = require('../models/applications');
+const {validateApplication} = require('../controllers/validation');
+const can = require('../permissions/applications');
+
+const router = Router({prefix: '/api/v1/applications'});
+
+
+// applications routes
+router.get('/all', getAll);
+router.post('/all', bodyParser(), validateApplication, createApplication);
+router.get('/:id([0-9]{1,})', getById);
+router.put('/:id([0-9]{1,})', auth, bodyParser(), validateApplication, updateApplication);
+router.del('/:id([0-9]{1,})', auth, deleteApplication);
+
+// application status routes
+router.get('/status/pending', getByPendingStatus);
+router.get('/status/accepted', getByAcceptedStatus);
+router.get('/status/rejected', getByRejectedStatus);
+
+
+/**
+ * getAll
+ * 
+ * @description Returns all applications from the DataBase.
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function getAll(ctx, next) {
+  const {page=1, limit=100, order="id", direction='ASC'} = ctx.request.query;
+  const result = await applications.getAll(page, limit, order, direction);
+  if (result.length) {
+    ctx.body = result;
+  }
+}
+
+
+/**
+ * getById
+ * 
+ * @decription Returns an application based on the ID
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function getById(ctx, next) {
+  const id = ctx.params.id;
+  const result = await applications.getById(id);
+  if (result.length) {
+    const application = result[0];
+    ctx.body = application;
+  }
+}
+
+
+/**
+ * createApplication
+ * 
+ * @description Creates a new application in the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function createApplication(ctx, next) {
+  const body = ctx.request.body;
+  const result = await applications.add(body);
+  if (result.affectedRows) {
+    const id = result.insertId;
+    ctx.status = 201;
+    ctx.body = {ID: id, created: true, link: `${ctx.request.path}/${id}`};
+  }
+}
+
+/**
+ * updateApplication
+ * 
+ * @description Updates application in the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function updateApplication(ctx, next) {
+  const id = ctx.params.id;
+  let result = await applications.getById(id);  // check it exists
+  if (result.length) {
+    let application = result[0];
+		const permission = can.update(ctx.state.user, application);
+		if (!permission.granted) {
+      ctx.status = 403;
+    } else {
+			// exclude fields that should not be updated
+			const {ID, firstName, lastName, email, ...body} = ctx.request.body;
+			// overwrite updatable fields with remaining body data
+			Object.assign(application, body);
+			result = await applications.update(application);
+			if (result.affectedRows) {
+				ctx.body = {ID: id, updated: true, link: `${ctx.host}${ctx.request.path}`};
+			}
+    }
+  }
+}
+
+/**
+ * deleteApplication
+ * 
+ * @description Deletes application from the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function deleteApplication(ctx, next) {
+	const permission = can.delete(ctx.state.user);
+  if (!permission.granted) {
+    ctx.status = 403;
+  } else {
+		const id = ctx.params.id;
+		const result = await appications.delById(id);
+		if (result.affectedRows) {
+    ctx.body = {ID: id, deleted: true}
+		}
+  }
+}
+
+async function getByPendingStatus(ctx) {
+  const status = ctx.params.id;
+  const result = await applications.getByPendingStatus(status);
+  if (result.length) {
+    ctx.body = result;
+  }
+}
+
+async function getByAcceptedStatus(ctx) {
+  const status = ctx.params.id;
+  const result = await applications.getByAcceptedStatus(status);
+  if (result.length) {
+    ctx.body = result;
+  }
+}
+
+async function getByRejectedStatus(ctx) {
+  const status = ctx.params.id;
+  const result = await applications.getByRejectedStatus(status);
+  if (result.length) {
+    ctx.body = result;
+  }
+}
+
+
+module.exports = router;
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/routes_users.js.html b/docs/jsdocs/routes_users.js.html new file mode 100644 index 0000000..db3842e --- /dev/null +++ b/docs/jsdocs/routes_users.js.html @@ -0,0 +1,203 @@ + + + + + JSDoc: Source: routes/users.js + + + + + + + + + + +
+ +

Source: routes/users.js

+ + + + + + +
+
+
/**
+ * Routes for users
+ * 
+ * @module routes/users
+ * @author Miltos Skondras
+ */
+
+const Router = require('koa-router');
+const bodyParser = require('koa-bodyparser');
+const model = require('../models/users');
+const auth = require('../controllers/auth');
+const {validateUser} = require('../controllers/validation');
+const can = require('../permissions/users');
+
+const prefix = '/api/v1/users';
+const router = Router({prefix: prefix});
+
+
+router.get('/', auth, getAll);
+router.post('/', bodyParser(), validateUser, createUser);
+router.post('/login', auth, login);
+router.get('/:id([0-9]{1,})', auth, getById);
+router.put('/:id([0-9]{1,})', auth, bodyParser(), validateUser, updateUser);
+router.del('/:id([0-9]{1,})', auth, deleteUser);
+
+/** 
+ * login
+ * 
+ * @description Returns user information 
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback 
+ * 
+ */
+async function login(ctx, next) {
+  // return any details needed by the client
+  const {ID, username, email, avatarURL} = ctx.state.user
+  const links = {
+    self: `${ctx.protocol}://${ctx.host}${prefix}/${ID}`
+  }
+  ctx.body = {ID, username, email, avatarURL, links};
+}
+
+/**
+ * getAll
+ * 
+ * @description Returns all users from the DataBase.
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function getAll(ctx, next) {
+  const permission = can.readAll(ctx.state.user);
+  if (!permission.granted) {
+    ctx.status = 403;
+  } else {
+    const result = await model.getAll();
+    if (result.length) {
+      ctx.body = result;
+    }    
+  }
+}
+
+/**
+ * getById
+ * 
+ * @decription Returns a user based on the ID
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function getById(ctx, next) {
+  const id = ctx.params.id;
+  const result = await model.getById(id);
+  if (result.length) {
+    const data = result[0]
+    const permission = can.read(ctx.state.user, data);
+    if (!permission.granted) {
+      ctx.status = 403;
+    } else {
+      ctx.body = permission.filter(data);
+    }
+  }
+}
+
+
+/**
+ * createUser
+ * 
+ * @description Creates a new user in the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function createUser(ctx, next) {
+  const body = ctx.request.body;
+  const result = await model.add(body);
+  if (result.affectedRows) {
+    const id = result.insertId;
+    ctx.status = 201;
+    ctx.body = {ID: id, created: true, link: `${ctx.request.path}/${id}`};
+  }
+}
+
+/**
+ * updateUser
+ * 
+ * @description Updates a user in the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function updateUser(ctx, next) {
+  const id = ctx.params.id;
+  let result = await model.getById(id);  // check it exists
+  if (result.length) {
+    let data = result[0];
+    const permission = can.update(ctx.state.user, data);
+    if (!permission.granted) {
+      ctx.status = 403;
+    } else {
+      // exclude fields that should not be updated
+      const newData = permission.filter(ctx.request.body);
+      Object.assign(newData, {ID: id}); // overwrite updatable fields with body data
+      result = await model.update(newData);
+      if (result.affectedRows) {
+        ctx.body = {ID: id, updated: true, link: ctx.request.path};
+      }
+    }
+  }
+}
+
+/**
+ * deleteUser
+ * 
+ * @description Deletes a user from the Database
+ * @param {object} ctx - Context object of HTTP Request
+ * @param {function} next - Callback
+ */
+async function deleteUser(ctx) {
+  const id = ctx.params.id;
+  let result = await model.getById(id);
+  if (result.length) {
+    const data = result[0];
+    console.log("trying to delete", data);
+    const permission = can.delete(ctx.state.user, data);
+    if (!permission.granted) {
+      ctx.status = 403;
+    } else {
+      result = await model.delById(id);
+      if (result.affectedRows) {
+        ctx.body = {ID: id, deleted: true}
+      }      
+    }
+  }
+}
+
+module.exports = router;
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/docs/jsdocs/strategies_basic.js.html b/docs/jsdocs/strategies_basic.js.html new file mode 100644 index 0000000..a483139 --- /dev/null +++ b/docs/jsdocs/strategies_basic.js.html @@ -0,0 +1,103 @@ + + + + + JSDoc: Source: strategies/basic.js + + + + + + + + + + +
+ +

Source: strategies/basic.js

+ + + + + + +
+
+
/**
+ * User authentication strategy
+ * 
+ * @module strategies/basic
+ * @author Miltos Skondras
+ */
+
+const BasicStrategy = require('passport-http').BasicStrategy;
+const users = require('../models/users');
+const bcrypt = require('bcrypt');
+
+const verifyPassword = function (user, password) {
+  // compare hash of password with the stored hash in the DB
+  const isMatch = bcrypt.compareSync(password, user.password);
+  return isMatch;
+}
+
+/**
+ * checkUserAndPass
+ * 
+ * @description Authenticates user by checking their info in the database
+ * @param {string} username - Username of user
+ * @param {string} password - Password of user
+ * @param {function} done - Callback
+ */
+const checkUserAndPass = async (username, password, done) => {
+  // look up the user and check the password if the user exists
+  // call done() with either an error or the user, depending on outcome
+  let result;
+
+  try {
+    result = await users.findByUsername(username);
+  } catch (error) {
+    console.error(`Error during authentication for user ${username}`);
+    return done(error);
+  }
+
+  if (result.length) {
+    const user = result[0];
+    if (verifyPassword(user, password)) {
+      console.log(`Successfully authenticated user ${username}`);
+      return done(null, user);
+    } else {
+      console.log(`Password incorrect for user ${username}`);
+    }
+  } else {
+    console.log(`No user found with username ${username}`);
+  }
+  return done(null, false);
+}
+
+const strategy = new BasicStrategy(checkUserAndPass);
+module.exports = strategy;
+
+
+ + + + +
+ + + +
+ + + + + + + diff --git a/models/applications.js b/models/applications.js index 69195ae..70b718d 100644 --- a/models/applications.js +++ b/models/applications.js @@ -1,6 +1,18 @@ +/** + * Database module for the application modification + * + * @module models/applications + * @author Miltos Skondras + */ + const db = require('../helpers/database'); -//list all the applications in the database +/** + * getAll + * + * @description Returns all applications + * @return {object} Objects containing application data + */ exports.getAll = async function getAll (page, limit, order, direction) { const offset = (page - 1) * limit; let query; @@ -14,7 +26,13 @@ exports.getAll = async function getAll (page, limit, order, direction) { return data; } -//get a single application by its id +/** + * getById + * + * @description Returns a single application based on its ID + * @param {number} id - The ID of the application + * @return {object} Object containing information on that specific application + */ exports.getById = async function getById (id) { const query = "SELECT * FROM applications WHERE ID = ?;"; const values = [id]; @@ -22,14 +40,26 @@ exports.getById = async function getById (id) { return data; } -//create a new application in the database +/** + * add + * + * @description Adds an application to the database + * @param {object} application - Application data in JSON format + * @return {object} Response from database + */ exports.add = async function add (application) { const query = "INSERT INTO applications SET ?"; const data = await db.run_query(query, application); return data; } -//delete an application by its id +/** + * delById + * + * @description Deletes an application from the database based on its ID + * @param {number} id - The ID of the application that will be deleted + * @return {object} Response from database + */ exports.delById = async function delById (id) { const query = "DELETE FROM appications WHERE ID = ?;"; const values = [id]; @@ -37,7 +67,13 @@ exports.delById = async function delById (id) { return data; } -//update an existing application +/** + * update + * + * @description Updates an application from the database based on its ID + * @param {number} application - The ID of the application that will be updated + * @return {object} Response from database + */ exports.update = async function update (appication) { const query = "UPDATE applications SET ? WHERE ID = ?;"; const values = [appication, appication.ID]; diff --git a/models/users.js b/models/users.js index 3c10e30..2ab62e8 100644 --- a/models/users.js +++ b/models/users.js @@ -1,7 +1,20 @@ +/** + * Database module for the user modification + * + * @module models/users + * @author Miltos Skondras + */ + const db = require('../helpers/database'); const bcrypt = require('bcrypt'); -//get a single user by its id +/** + * getById + * + * @description Returns a single user based on their ID + * @param {object} id - The ID of the user + * @return {object} Object containing information on that specific user + */ exports.getById = async function getById (id) { const query = "SELECT * FROM users WHERE ID = ?;"; const values = [id]; @@ -9,21 +22,38 @@ exports.getById = async function getById (id) { return data; } -//get a single user by the (unique) username +/** + * findByUsername + * + * @description Returns a single user based on their username + * @param {string} username - The username of the user + * @return {object }Object containing information on that specific user + */ exports.findByUsername = async function getByUsername(username) { const query = "SELECT * FROM users WHERE username = ?;"; const user = await db.run_query(query, username); return user; } -//list all the users in the database +/** + * getAll + * + * @description Returns all users + * @return {object} Objects containing user data + */ exports.getAll = async function getAll (page, limit, order) { const query = "SELECT * FROM users;"; const data = await db.run_query(query); return data; } -//create a new user in the database +/** + * add + * + * @description Adds a user to the database + * @param {object} user - User data in JSON format + * @return {object} Response from database + */ exports.add = async function add (user) { const query = "INSERT INTO users SET ?"; const password = user.password; @@ -33,7 +63,13 @@ exports.add = async function add (user) { return data; } -//delete a user by its id +/** + * delById + * + * @description Deletes a user from the database based on its ID + * @param {number} id - The ID of the user that will be deleted + * @return {object} Response from database + */ exports.delById = async function delById (id) { const query = "DELETE FROM users WHERE ID = ?;"; const values = [id]; @@ -41,7 +77,13 @@ exports.delById = async function delById (id) { return data; } -//update an existing user +/** + * update + * + * @description Updates a user from the database based on its ID + * @param {number} user - The ID of the user that will be updated + * @return {object} Response from database + */ exports.update = async function update (user) { const query = "UPDATE users SET ? WHERE ID = ?;"; const values = [user, user.ID]; diff --git a/permissions/applications.js b/permissions/applications.js index 6d4f050..ecddf3a 100644 --- a/permissions/applications.js +++ b/permissions/applications.js @@ -1,3 +1,10 @@ +/** + * Permissions module for the applications + * + * @module permissions/applications + * @author Miltos Skondras + */ + const AccessControl = require('role-acl'); const ac = new AccessControl(); @@ -25,7 +32,15 @@ ac .on('application'); - +/** + * update + * + * @description Checks whether the user has permission to update the application + * + * @param {object} requester - The user object of the person requesting + * @param {object} data - The data of the application + * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action + */ exports.update = (requester, data) => { console.log(requester) @@ -38,6 +53,16 @@ exports.update = (requester, data) => { .on('application'); } +/** + * delete + * + * @description Checks whether the user has permission to delete the application + * + * @param {object} requester - The user object of the person requesting + * @param {object} data - The data of the application + * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action + */ + exports.delete = (requester) => { return ac .can(requester.role) diff --git a/permissions/users.js b/permissions/users.js index bf76d6a..4940c3c 100644 --- a/permissions/users.js +++ b/permissions/users.js @@ -1,3 +1,10 @@ +/** + * Permissions module for the users + * + * @module permissions/users + * @author Miltos Skondras + */ + const AccessControl = require('role-acl'); const ac = new AccessControl(); @@ -35,6 +42,13 @@ ac .execute('delete') .on('user'); +/** + * readAll + * @description Checks whether user has permission to get all the users + * + * @param {object} requester - The user object of the person requesting + * @returns {boolean} Boolean response on whether or not the user has permission to complete this action + */ exports.readAll = (requester) => { return ac @@ -44,6 +58,16 @@ exports.readAll = (requester) => { .on('users'); } +/** + * read + * + * @description Checks whether the user has permission to read user data + * + * @param {object} requester - The user object of the person requesting + * @param {object} data - The data of the application + * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action + */ + exports.read = (requester, data) => { return ac .can(requester.role) @@ -53,6 +77,16 @@ exports.read = (requester, data) => { .on('user'); } +/** + * update + * + * @description Checks whether the user has permission to update the user + * + * @param {object} requester - The user object of the person requesting + * @param {object} data - The data of the user + * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action + */ + exports.update = (requester, data) => { return ac .can(requester.role) @@ -62,6 +96,16 @@ exports.update = (requester, data) => { .on('user'); } +/** + * delete + * + * @description Checks whether the user has permission to delete a user + * + * @param {object} requester - The user object of the person requesting + * @param {object} data - The data of the user + * @boolean {boolean} Boolean response on whether or not the user has permission to complete this action + */ + exports.delete = (requester, data) => { return ac .can(requester.role) diff --git a/routes/applications.js b/routes/applications.js index de99383..653186b 100644 --- a/routes/applications.js +++ b/routes/applications.js @@ -1,3 +1,10 @@ +/** + * Routes for the application + * + * @module routes/applications + * @author Miltos Skondras + */ + const Router = require('koa-router'); const bodyParser = require('koa-bodyparser'); @@ -21,7 +28,15 @@ router.get('/status/pending', getByPendingStatus); router.get('/status/accepted', getByAcceptedStatus); router.get('/status/rejected', getByRejectedStatus); -async function getAll(ctx) { + +/** + * getAll + * + * @description Returns all applications from the DataBase. + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function getAll(ctx, next) { const {page=1, limit=100, order="id", direction='ASC'} = ctx.request.query; const result = await applications.getAll(page, limit, order, direction); if (result.length) { @@ -29,7 +44,15 @@ async function getAll(ctx) { } } -async function getById(ctx) { + +/** + * getById + * + * @decription Returns an application based on the ID + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function getById(ctx, next) { const id = ctx.params.id; const result = await applications.getById(id); if (result.length) { @@ -38,7 +61,15 @@ async function getById(ctx) { } } -async function createApplication(ctx) { + +/** + * createApplication + * + * @description Creates a new application in the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function createApplication(ctx, next) { const body = ctx.request.body; const result = await applications.add(body); if (result.affectedRows) { @@ -48,7 +79,14 @@ async function createApplication(ctx) { } } -async function updateApplication(ctx) { +/** + * updateApplication + * + * @description Updates application in the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function updateApplication(ctx, next) { const id = ctx.params.id; let result = await applications.getById(id); // check it exists if (result.length) { @@ -61,15 +99,22 @@ async function updateApplication(ctx) { const {ID, firstName, lastName, email, ...body} = ctx.request.body; // overwrite updatable fields with remaining body data Object.assign(application, body); - result = await applications.update(article); + result = await applications.update(application); if (result.affectedRows) { - ctx.body = {ID: id, updated: true, link: ctx.request.path}; + ctx.body = {ID: id, updated: true, link: `${ctx.host}${ctx.request.path}`}; } } } } -async function deleteApplication(ctx) { +/** + * deleteApplication + * + * @description Deletes application from the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function deleteApplication(ctx, next) { const permission = can.delete(ctx.state.user); if (!permission.granted) { ctx.status = 403; diff --git a/routes/users.js b/routes/users.js index d2d00d9..6754596 100644 --- a/routes/users.js +++ b/routes/users.js @@ -1,3 +1,10 @@ +/** + * Routes for users + * + * @module routes/users + * @author Miltos Skondras + */ + const Router = require('koa-router'); const bodyParser = require('koa-bodyparser'); const model = require('../models/users'); @@ -16,8 +23,15 @@ router.get('/:id([0-9]{1,})', auth, getById); router.put('/:id([0-9]{1,})', auth, bodyParser(), validateUser, updateUser); router.del('/:id([0-9]{1,})', auth, deleteUser); - -async function login(ctx) { +/** + * login + * + * @description Returns user information + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + * + */ +async function login(ctx, next) { // return any details needed by the client const {ID, username, email, avatarURL} = ctx.state.user const links = { @@ -26,7 +40,14 @@ async function login(ctx) { ctx.body = {ID, username, email, avatarURL, links}; } -async function getAll(ctx) { +/** + * getAll + * + * @description Returns all users from the DataBase. + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function getAll(ctx, next) { const permission = can.readAll(ctx.state.user); if (!permission.granted) { ctx.status = 403; @@ -38,8 +59,14 @@ async function getAll(ctx) { } } - -async function getById(ctx) { +/** + * getById + * + * @decription Returns a user based on the ID + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function getById(ctx, next) { const id = ctx.params.id; const result = await model.getById(id); if (result.length) { @@ -54,8 +81,14 @@ async function getById(ctx) { } - -async function createUser(ctx) { +/** + * createUser + * + * @description Creates a new user in the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function createUser(ctx, next) { const body = ctx.request.body; const result = await model.add(body); if (result.affectedRows) { @@ -65,7 +98,14 @@ async function createUser(ctx) { } } -async function updateUser(ctx) { +/** + * updateUser + * + * @description Updates a user in the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ +async function updateUser(ctx, next) { const id = ctx.params.id; let result = await model.getById(id); // check it exists if (result.length) { @@ -85,6 +125,13 @@ async function updateUser(ctx) { } } +/** + * deleteUser + * + * @description Deletes a user from the Database + * @param {object} ctx - Context object of HTTP Request + * @param {function} next - Callback + */ async function deleteUser(ctx) { const id = ctx.params.id; let result = await model.getById(id); diff --git a/schemas/user.json b/schemas/user.json index 89fcc70..fe1ea97 100644 --- a/schemas/user.json +++ b/schemas/user.json @@ -43,7 +43,7 @@ } }, "required": ["username", "email", "password"], - "additionalProperties": false + "additionalProperties": true }, @@ -115,7 +115,7 @@ "minLength": 6 } }, - "additionalProperties": false + "additionalProperties": true }, diff --git a/strategies/basic.js b/strategies/basic.js index 245135f..f7127ca 100644 --- a/strategies/basic.js +++ b/strategies/basic.js @@ -1,3 +1,10 @@ +/** + * User authentication strategy + * + * @module strategies/basic + * @author Miltos Skondras + */ + const BasicStrategy = require('passport-http').BasicStrategy; const users = require('../models/users'); const bcrypt = require('bcrypt'); @@ -8,6 +15,14 @@ const verifyPassword = function (user, password) { return isMatch; } +/** + * checkUserAndPass + * + * @description Authenticates user by checking their info in the database + * @param {string} username - Username of user + * @param {string} password - Password of user + * @param {function} done - Callback + */ const checkUserAndPass = async (username, password, done) => { // look up the user and check the password if the user exists // call done() with either an error or the user, depending on outcome