{"id":14957612,"url":"https://github.com/arviteri/footing","last_synced_at":"2025-07-22T19:03:40.353Z","repository":{"id":36149328,"uuid":"165903503","full_name":"arviteri/Footing","owner":"arviteri","description":"A foundation for developing APIs with Node.js and Express. ","archived":false,"fork":false,"pushed_at":"2023-01-03T16:12:47.000Z","size":1411,"stargazers_count":62,"open_issues_count":19,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-02T07:48:21.306Z","etag":null,"topics":["api","express","express-js","foundation","framework","javascript","node","nodejs","rest","restful","server"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arviteri.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-15T18:36:44.000Z","updated_at":"2023-05-12T16:53:36.000Z","dependencies_parsed_at":"2023-01-16T23:45:20.028Z","dependency_job_id":null,"html_url":"https://github.com/arviteri/Footing","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/arviteri/Footing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arviteri%2FFooting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arviteri%2FFooting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arviteri%2FFooting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arviteri%2FFooting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arviteri","download_url":"https://codeload.github.com/arviteri/Footing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arviteri%2FFooting/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266553968,"owners_count":23947244,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","express","express-js","foundation","framework","javascript","node","nodejs","rest","restful","server"],"created_at":"2024-09-24T13:15:14.373Z","updated_at":"2025-07-22T19:03:40.100Z","avatar_url":"https://github.com/arviteri.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u0026nbsp;\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://i.ibb.co/qRjRw2g/logo-f.png\" height=100\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://travis-ci.org/arviteri/Footing\" alt=\"Travis-CI\"\u003e\u003cimg src=\"https://travis-ci.org/arviteri/Footing.svg?branch=master\"\u003e\u003c/a\u003e\u0026nbsp;\u0026nbsp;\u0026nbsp;\n\t\u003ca href=\"https://opensource.org/licenses/MIT\" alt=\"License:MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n__UPDATE:__ A version of Footing which is designed for storing application data using MongoDB has been created. It can be found in the `feature/mongodb-app` branch. The default version stores application data with MySQL. A command line interface to create Footing projects is currently in the works. It can be found on the `cli` branch.\n\n\u003cbr /\u003e\n\nFooting is a foundation for developing APIs with Node.js and Express. The project is designed in a way to make it easy for developers to build secure APIs with minimal setup. Footing provides the ability to define public or private routes with or without CSRF protection. \n\nRoutes that are predefined and come with Footing include ones that allow registering users, authenticating users, and deleting users. Routes for testing CSRF and authentication functionality are also included. \n\nFooting's purpose is to enable developers to create APIs without needing to implement an authentication system.\n\n# Index\n- ### [What's Included?](#included) \n- ### [What's Not Included?](#notincluded) \n- ### [Requirements](#req)  \n- ### [Getting Set Up](#setup)  \n- ### [Usage](#use) \n\t- #### [Environment Variables](#env)\n\t- #### [Changing Default Routes](#defaultroutes)\n\t- #### [Defining New Routes](#defroutes)\n\t- #### [Making Requests](#makerequests)\n\t-  #### [Adding XSS Protection](#xss)\n- ### [Developer](https://github.com/arviteri/Footing/blob/master/docs/DEVELOPER.md)\n\n\u003ca id=\"included\"/\u003e\n\n# What's Included?\n\nFooting includes...\n- Environment variables for easy setup (provided by npm package `dotenv`).\n- An authentication system.\n- CSRF protection (provided by npm package `csurf`).\n- SQL Injection protection (__for predefined routes only__).\n- Integration tests for predefined routes.\n\n### The Authentication System\nRoutes that are private will require a Bearer token in the authentication header of the request. Upon a successful login request, an authentication token will be stored as a cookie, and also returned in the form of a JSON response. The token is in the form of a JWT, and it's secret is a unique ID that is stored in the user's session. The authentication system protects routes by first verifying that the token in the authentication header matches that of the cookie. Secondly, the system verifies the token with the secret that is stored in the user's session.\n\nIt's important to note that upon a successful login request, the user's session is regenerated and a new CSRF token will be returned. The CSRF token used to make the login request will no longer be valid.\n\n\u003ca id=\"notincluded\"/\u003e\n\n# What's Not Included?\n\nThe following list serves to warn users of what is not included.  It does not serve as a comprehensive list of what is not included with Footing. \n\nFooting __does  not  include__...\n- Email verification for authentication system.\n- Password restrictions for authentication system.\n- XSS protection (data sanitization) for any input.\n- SQL Injection prevention for routes that are defined by the developer. \n- Anything else not listed.\n\n\u003ca id=\"req\" /\u003e\n\n# Requirements\n\nRequirements for developing REST APIs with Footing include...\n- MySQL database (used for application data).\n- MongoDB database (used for managing sessions).\n- Node.js ( \u003e= v8.11.1, it's recommended to be used with v10.15.1)\n\n__Disclaimer:__ Integration tests have been tested for Node.js  v10.15.3. The project was originally developed using Node.js v8.11.1; however, the integration tests will fail on v8.11.1 due to the version of npm package `supertest` that v8.11.1 uses. That specific version of `supertest` has an issue making requests and receiving responses that include more than one cookie. \n\n\u003ca id=\"setup\"/\u003e\n\n# Getting Set Up\n\n1. Clone the repository and `cd` into the root of the project directory.\n2. Run `npm install` to install the dependencies.\n3. Duplicate the `.env.dist` file and rename it to `.env`\n4. Open the `.env` file and set the values for the environment variables (suggested/default values are included).\n5. Make sure that MySQL and MongoDB servers are running.\n6. (Optional) Run `npm test` to make sure the project is working correctly.\n7. Run `npm start` to start the server. \n\n\u003ca id=\"use\"/\u003e\n\n# Usage\n\n\u003ca id=\"env\"/\u003e\n\n### Environment Variables\nTo configure environment variables, duplicate the `.env.dist` file and rename it to `.env`. Environment variables are predefined with default values. Change them as needed. The variables are used for...\n- Defining the port to serve the application on.\n- Setting up a connection to a MySQL database.\n- Setting up a connection to a MongoDB database.\n- Deciding on salt rounds for hashing passwords.\n- Deciding on a secret for session data. \n\n\nEnvironment variables included are...\n- __PORT__ - Port the application will be served on.\n- __MySQL_HOST__ - Host for MySQL connection. \n- __MySQL_PORT__ - Port for MySQL connection. The default is 3306.  \n- __MySQL_USER__ - User for MySQL connection. \n- __MySQL_PWD__ - Password for MySQL connection.\n- __MySQL_DB__ - Database name for MySQL database.\n- __MySQL_USERS_TBL__ - The name of the table that stores user entities in the MySQL database.\n- __MongoDB_URI__ - The URI of the MongoDB database used for sessions.\n- __BCRYPT_SALT_ROUNDS__ - Salt rounds for Bcrypt to hash passwords. \n- __SESSION_SECRET__ - Secret for Express sessions. \n\n\u003cbr/\u003e\n\u003ca id=\"defaultroutes\"/\u003e\n\n### Changing Default Routes\n\nThe routes that have already been defined are for...\n- User signup - `/signup`.\n- User login - `/login`.\n- Delete user -  `/delete_account`.\n- Obtain CSRF token - `/c/tkn`.\n- Status - `/status`.\n- Testing routes that include CSRF protection that don't require authentication - `/test/csrf`.\n- Testing routes that don't include CSRF protection that require authentication - `/test/auth`.\n- Testing routes that include CSRF protection and require authentication - `/test/auth_csrf`.\n\nThe routes above are defined in the `src/config/routes.js` file. They are implemented in the `src/routes/api/identification.js` file and the `src/routes/api/health.js` file. \n\n__To change the default route endpoints, it is recommended that they are changed in the `src/config/routes.js` file and not in the implementation file. This is recommended because the integration tests rely on the `src/config/routes.js` file to test the correct routes.__\n\n__Changing the route endpoints in the `src/config/routes.js` file will ensure that the integration tests will still work correctly.__\n\n\u003cbr/\u003e\n\u003ca id=\"defroutes\"/\u003e\n\n### Defining New Routes\n\nTo define new routes, create a new routing file in the `src/routes/api/` directory. Footing has been designed to \tautomatically `require` all files in that directory. _The file should be set up as so..._\n```\n/**\n * Your routing file\n */\n\nmodule.exports = function(app, config, routes) {\n\t// Define routes here.\n}\n```\n\nEach routing file is automatically passed the app, config and routes variables. This way, all routing files can access any global application variables.\n\n\u003cbr /\u003e\n\nTo require requests to be authenticated, the route receiving the request will need to use the RequestAuthenticator function found in `src/routes/middleware/auth_middleware.js` as middleware. This function requires an instance of the AuthHandler class found in the `src/handlers/auth_handler.js` to be passed to it. _See the example below._\n\n\u003cbr /\u003e\n\n```\n/**\n * Your routing file\n */\n\nconst AuthHandler = require('../../handlers/auth_handler.js');\nconst RequestAuthenticator = require('../middleware/auth_middleware.js');\n\nmodule.exports = function(app, config, routes) {\n\n\tconst requestAuthenticator = RequestAuthenticator(new AuthHandler(config));\n\n\t// Define routes here.\n\troutes.protected.post('/example', requestAuthenticator, function(res, req) {\n\t\t/* ... */\n\t});\n}\n```\n\n\u003cbr /\u003e\n\n__Unprotected routes__ (routes that __do not include__ CSRF protection) are used by the router variables `routes.unprotected`.\n__Protected routes__ (routes that __include__ CSRF protection) are used by the router variables `routes.protected`.\n\n\u003cbr/\u003e\n\n__Example of defining a new PUBLIC route _without_ CSRF protection.__\n~~~\nroutes.unprotected.post('/public_without_CSRF', function(res, req) {\n    return res.status(200).json({\"200\":\"Unathenticated\"});\n});\n~~~\n\u003cbr /\u003e\n\n__Example of defining a new PUBLIC route _with_ CSRF protection__\n~~~\nroutes.protected.post('/public_with_CSRF', function(res, req) {\n\t\treturn res.status(200).json({\"200\":\"Unathenticated\"});\n});\n~~~\n\u003cbr /\u003e\n\n__Example of defining a new PRIVATE route _without_ CSRF protection__\n~~~\nroutes.unprotected.post('/auth_without_CSRF', requestAuthethenticator, function(res, req) {\n    return res.status(200).json({\"200\":\"Authenticated\"});\n});\n~~~\n\u003cbr /\u003e\n\n__Example of defining a new PRIVATE route _with_ CSRF protection__ \n~~~\nroutes.protected.post('/auth_with_CSRF', requestAuthethenticator, function(res, req) {\n    return res.status(200).json({\"200\":\"Authenticated\"});\n});\n~~~\n\n\u003cbr/\u003e\n\u003ca id=\"makerequests\"/\u003e\n\n### Making Requests\n__Obtaining a CSRF token:__ \t`GET: http://localhost:port/c/tkn`\n\n__User Signup:__\n```\nPOST: http://localhost:port/signup\n{\n\t\"email\": \"test@example.com\",\n\t\"password\": \"password\",\n\t\"confirmPassword\": \"password\",\n\t\"_csrf\": \"N2MbkPwA-3cJSavajIlsW_61OPZ_5uoQr6QU\"\n}\n```\n\n__User Login:__\n```\nPOST: http://localhost:port/login\n{\n\t\"email\": \"test@example.com\",\n\t\"password\": \"password\",\n\t\"_csrf\": \"N2MbkPwA-3cJSavajIlsW_61OPZ_5uoQr6QU\"\n}\n```\n\n__Private Route without CSRF protection:__\n```\nPOST: http://localhost:port/test/auth\nHEADER: Authorization - Bearer {jwtAuthTokenValueHere}\n```\n\n__Private Route with CSRF protection:__\n```\nPOST: http://localhost:port/test/auth\nHEADER: Authorization - Bearer {jwtAuthTokenValueHere}\n{\n\t\"_csrf\": \"N2MbkPwA-3cJSavajIlsW_61OPZ_5uoQr6QU\"\n}\n```\n\n\u003cbr/\u003e\n\u003ca id=\"xss\"/\u003e\n\n### Adding XSS Protection\nDue to the amount of npm packages that offer data sanitization, and the lack of regulation/validity that is available for such packages, Footing does not offer XSS protection/data sanitization functions. However, comments are available in suggested locations for sanitizing input data. These comments are located in the `src/controllers/user_controller.js` file.\n\nIt is recommended to implement a middleware function that sanitizes all input data for all requests. \n\n\n\u003ca id=\"develop\"/\u003e\n\n# Developer\n\nThe developer doc can be found in `/docs`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farviteri%2Ffooting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farviteri%2Ffooting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farviteri%2Ffooting/lists"}