{"id":17151121,"url":"https://github.com/nvinuesa/skeleton-ecrm-nodejs","last_synced_at":"2025-07-22T03:31:50.237Z","repository":{"id":144576685,"uuid":"86452202","full_name":"nvinuesa/skeleton-ecrm-nodejs","owner":"nvinuesa","description":"Customer Relationship Management module skeleton in NodeJS","archived":false,"fork":false,"pushed_at":"2017-06-30T14:56:34.000Z","size":29,"stargazers_count":5,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-20T12:10:53.874Z","etag":null,"topics":["crm","jwt","mongodb","nodejs","redis"],"latest_commit_sha":null,"homepage":null,"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/nvinuesa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-28T11:30:49.000Z","updated_at":"2020-08-07T19:41:46.000Z","dependencies_parsed_at":"2023-03-22T12:17:32.730Z","dependency_job_id":null,"html_url":"https://github.com/nvinuesa/skeleton-ecrm-nodejs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nvinuesa/skeleton-ecrm-nodejs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvinuesa%2Fskeleton-ecrm-nodejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvinuesa%2Fskeleton-ecrm-nodejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvinuesa%2Fskeleton-ecrm-nodejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvinuesa%2Fskeleton-ecrm-nodejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvinuesa","download_url":"https://codeload.github.com/nvinuesa/skeleton-ecrm-nodejs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvinuesa%2Fskeleton-ecrm-nodejs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266419580,"owners_count":23925790,"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":["crm","jwt","mongodb","nodejs","redis"],"created_at":"2024-10-14T21:37:17.387Z","updated_at":"2025-07-22T03:31:50.227Z","avatar_url":"https://github.com/nvinuesa.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/underscorenico/skeleton-ecrm-nodejs.svg?branch=master)](https://travis-ci.org/underscorenico/skeleton-ecrm-nodejs)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/underscorenico/skeleton-ecrm-nodejs/master/LICENSE.txt)\n\n# skeleton-ecrm-nodejs\n\nCustomer Relationship Management module skeleton in NodeJS\n\u003cbr\u003e\nVisit [https://underscorenico.github.io/blog/2017/04/21/nodejs-ecrm-jwt/][blog] for a more detailed tutorial.\n\n[blog]: https://underscorenico.github.io/blog/2017/04/21/nodejs-ecrm-jwt/\n\n## Usage\nClone the repo, install and launch:\n```\ngit clone https://github.com/underscorenico/skeleton-ecrm-nodejs.git\ncd skeleton-ecrm-nodejs\nnpm install\nnpm start\n```\nThe start script will run the server (using nodemon) on port 3000 (http://localhost:3000)\n## Overview\nThis skeleton provides an API for CRM (Customer Relationship Management). CRM is a central module in every e-commerce application since it manages users (buyers / sellers), organizations, sessions, etc.\n\u003cbr\u003e\nThe routes provide a very simple profile CRUD as well as the session management (login and logout).\n\u003cbr\u003e\n\u003cbr\u003e\n**Note**: For a working web app skeleton in Angular 2 check out [this repo][angular2].\n\n[angular2]: https://github.com/JunkyDeLuxe/angular4-starter\n\n### Profiles\nThe profile API contains 5 routes:\n \nMethod | URL (relative) | Description \n--- | --- | --- \nPOST | /profiles | Create a profile\nGET | /profiles/*{id}* | Retrieve a profile \t\nGET | /profiles | Retrieve all profiles\nPUT | /profiles/*{id}* | Update a profile \t\nDELETE | /profiles/*{id}* | Delete a profile \t\n\nThe ```profile``` model that is to be passed in the POST request is the following:\n\n```\n{\n  name: String,\n  email: String,\n  password: String\n}\n```\n\n### (Pseudo) Sessions\nThis module does not use sessions. Instead, it uses [Json Web Tokens (JWT)][jwt] for authentication and securing the routes.\n\u003cbr\u003e\nTwo routes are provided for login and logout:\n\nMethod | URL (relative) | Description \n--- | --- | --- \nPOST | /login | Log-in\nGET | /logout | Log-out\n\n\nJWT's library generates tokens that are stateless (i.e. tokens that carry every information needed in order to be authenticated). This feature makes them very useful for applications that (possibly) do not have access to cookies on the client side (e.g. mobile apps).\n\u003cbr\u003e\nIt's main drawback, however, is that you will have to manage the sessions yourself (because they are stateless).\n\u003cbr\u003e\nIn this skeleton, I provide you with a secure mechanism for token revocation (blacklisting tokens). This is needed when you want to make sure that when a user logs out, the previous token that the user obtained is now invalidated. \n\u003cbr\u003e\nThis was achieved by blacklisting the tokens either in an in-memory key-value store (that **must never** be used in production) or in a [Redis][redis] database.\n\u003cbr\u003e\nThe functions ```isTokenRevoked``` and ```logout``` in ```session-service.js``` implement this mechanism:\n\n```javascript\nexports.isTokenRevoked = function (email, tokenId, callback) {\n\n\tif (conf.redis) {\n\t\t// If redis is defined in the conf files\n\n\t\tconst port = conf.redis.port || '6379'; // Redis default port\n\t\tconst host = conf.redis.host || 'localhost';\n\n\t\tconst client = redis.createClient(port, host);\n\t\tclient.get(email, function (err, reply) {\n\t\t\tcallback(err, reply === tokenId);\n\t\t})\n\t} else {\n\t\t//\tElse we use the mem cache\n\n\t\tconst reply = memoryStore.get(email);\n\t\tcallback(null, reply === tokenId);\n\t}\n};\n\nexports.logout = function (email, tokenId, next) {\n\n\tif (conf.redis) {\n\t\t// If redis is defined in the conf files\n\n\t\tconst port = conf.redis.port || '6379'; // Redis default port\n\t\tconst host = conf.redis.host || 'localhost';\n\n\t\tconst client = redis.createClient(port, host);\n\t\tclient.set(email, tokenId, function (err) {\n\t\t\tnext(err);\n\t\t})\n\t} else {\n\t\t//\tElse we use the mem cache\n\n\t\tmemoryStore.set(email, tokenId);\n\t\tnext(null);\n\t}\n};\n```\n```isTokenRevoked``` is then passed to the [Express-jwt][expressjwt] middleware in order to filter requests with revoked tokens.\n\n[expressjwt]: https://github.com/auth0/express-jwt\n\nRedis is automatically configured for you, or you can set its hostname and port in the configuration files. \n\u003cbr\u003e\nFor example:\n\n```javascript\nmodule.exports = {\n\tredis: {\n\t  hostname: \"127.0.0.1\",\n\t  port: \"6379\"\n\t}\n};\n```\n\n[jwt]: https://jwt.io/\n[redis]: https://redis.io/\n\n## Contributing\n\nEveryone is welcome to contribute, either by adding features, solving bugs or helping with documentation.\n\u003cbr\u003e\nThis project embraces [the open code of conduct][codeofconduct] from the [TODO group][todogroup], therefore all of its channels should respect its guidelines.\n\u003cbr\u003e\n\n[codeofconduct]: http://todogroup.org/opencodeofconduct\n[todogroup]: http://todogroup.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvinuesa%2Fskeleton-ecrm-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvinuesa%2Fskeleton-ecrm-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvinuesa%2Fskeleton-ecrm-nodejs/lists"}