{"id":15793404,"url":"https://github.com/jrebecchi/nusid","last_synced_at":"2026-01-20T18:55:57.972Z","repository":{"id":41708316,"uuid":"132822296","full_name":"jrebecchi/NUSID","owner":"jrebecchi","description":"A generic user space you can use in all your Node.js apps. It contains everything, from the MongoDB database model to the dynamic views made with EJS, Bootstrap3 and AngularJS.","archived":false,"fork":false,"pushed_at":"2023-01-24T01:28:16.000Z","size":5302,"stargazers_count":1,"open_issues_count":9,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-05T09:02:58.595Z","etag":null,"topics":["framework","full","generic","import","mvc","node-js","nodejs","space","user","userspace"],"latest_commit_sha":null,"homepage":"https://nusid.net","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/jrebecchi.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2018-05-09T23:13:49.000Z","updated_at":"2021-05-13T07:54:18.000Z","dependencies_parsed_at":"2023-02-13T09:00:58.368Z","dependency_job_id":null,"html_url":"https://github.com/jrebecchi/NUSID","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jrebecchi/NUSID","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrebecchi%2FNUSID","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrebecchi%2FNUSID/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrebecchi%2FNUSID/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrebecchi%2FNUSID/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jrebecchi","download_url":"https://codeload.github.com/jrebecchi/NUSID/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jrebecchi%2FNUSID/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28609370,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["framework","full","generic","import","mvc","node-js","nodejs","space","user","userspace"],"created_at":"2024-10-04T23:10:51.465Z","updated_at":"2026-01-20T18:55:57.955Z","avatar_url":"https://github.com/jrebecchi.png","language":"JavaScript","readme":"![Node.js CI](https://github.com/jrebecchi/NUSID/workflows/Node.js%20CI/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/jrebecchi/NUSID/badge.svg?branch=master)](https://coveralls.io/github/jrebecchi/NUSID?branch=master)\n\n\n[![NUSID Logo](https://nusidpublicresources-xeqnuojpin.now.sh/Nusid_Banner_Logo_800px.jpg)](#)\n\nNUSID - Node.JS User Space for Idle Developers!\n\nNUSID is a generic user space you can use in all your [Node.js](http://nodejs.org) apps as a starting point. It contains everything, from the [MongoDB](https://www.mongodb.com/) database model to the dynamic views made with [EJS](http://ejs.co/), [Bootstrap3](http://getbootstrap.com/docs/3.3/) and [AngularJS](https://angularjs.org/). \n\nIf you are an idle developer NUSID is made for you!\n  \n![NUSID Screenshot](https://nusidpublicresources-xeqnuojpin.now.sh/login_screenshot.png)\n\n## Demo\n\nClick [here](https://nusid.net) to see a live demo!\n\n## Features\n  * Registration\n  * Login\n  * \"Remember me\" session login \n  * Email verification\n  * Password recovery\n  * Account modification\n  * Account deletion\n  * Input field validation rules for both the client \u0026 server side (centralized with Browserify)\n  * MongoDB User model with password encryption \u0026 salt\n  * CSRF protection\n  * Flash message manager\n  * Responsive design \n  * Designed in bundles similar to the [Symfony](https://symfony.com/) framework\n  * HTTP Strict Transport Security\n\n## Installation\n\nThis is a [Node.js](https://nodejs.org/en/) app working with [MongoDB](https://www.mongodb.com/). Before installing, [download and install Node.js](https://nodejs.org/en/download/).\nNode.js 0.10 or higher is required. You also need to have a distant access or a local installation of [MongoDB](https://www.mongodb.com/). \n\nInstallation is done using the\n[`git clone` command](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):\n\n```bash\n$ git clone https://github.com/jrebecchi/NUSID.git\n$ cd NUSID\n$ npm install\n```\n\nThen you need to rename the `app.js.exemple` file as `app.js`, and edit it to enter your email and [MongoDB](https://www.mongodb.com/) information:\n\n* [MongoDB](https://www.mongodb.com/) configuration (where will be stored the users) \n\n```js\nglobal.userDBOptions = {\n  hostname :\"dbuser:dbpassword@host.com\",\n  port :\"19150\",\n  database : \"user_management\"\n};\n```\n\n##### If you wish to use your local [MongoDB](https://www.mongodb.com/) use the following:\n\n```js\nglobal.userDBOptions = {\n\thostname :\"localhost\",\n\tport :\"27017\",\n\tdatabase : \"users\"\n}\n```\n\n* Email configuration (from where will be sent the administration emails)\n\n```js\nglobal.userspaceMailOptions = {\n  from: 'myemail@myhost.com', //email address\n  host: 'smtp.myhost.com', // hostname \n  secureConnection: true, // use SSL \n  port: 465, // port for secure SMTP \n  auth: {\n    user: 'username', //email login\n    pass: 'mypassword' //email password\n  }\n};\n```\nYou can have more options for the email parameters looking at the [nodemailer options](https://nodemailer.com).\n\n* Server configuration\n\nAdapt the following code to your installation configuration:\n```js\nserver.listen(process.env.PORT || 3000, process.env.IP || \"0.0.0.0\", function(){\n  const addr = server.address();\n  console.log(\"Server listening at\", addr.address + \":\" + addr.port);\n});\n```\nFinally launch this app with :\n\n```bash\n$ node app.js\n```\n\n**TIP!** You can deploy for free this NodeJS app on [Zeit](https://zeit.co)\n\n**TIP!** You can have a free MongoDB database on [MLab](https://mlab.com/)\n\n**TIP!** You can use a Gmail email by [allowing less secure app](https://myaccount.google.com/lesssecureapps)\n\n## Bundle architecture\n\nNUSID is designed in bundles using the MVC pattern. A bundle is simply a component which contains :\n* A router : Redirecting some given routes to its different controllers\n* Controlers : Responsible for sending responses the user requests\n* Models : To represent the data retrieved from the database and offer different treatment functions\n* Services : Any utility methods that can be used anywhere in the bundle\n* Views : template views that are sent back by the controllers to the users\n\n## Add your own bundles\n\nHere you are going to learn how to add our own bundles and extend this user space to create your own app ! As an exemple we are going to create a bundle named MyOwnBundle containing 2 routes, one to a public page and one to a private page that you can see only by being connected as a user.\n\n* Step 1: Create your bundle folder under the `bundles` directory\n\n```bash\n$ mkdir bundles/MyOwnBundle\n```\n\n* Step 2: Create the bundle structure with a `controller`, `model`, `router`, `service` and `views` folder \n\n```bash\n$ mkdir bundles/MyOwnBundle/controller \n$ mkdir bundles/MyOwnBundle/model \n$ mkdir bundles/MyOwnBundle/router \n$ mkdir bundles/MyOwnBundle/service \n$ mkdir bundles/MyOwnBundle/views\n$ mkdir bundles/MyOwnBundle/views/pages\n```\n\n* Step 3: Create the entry file of your bundle, the router, a controller and the 2 different views for the public page and the private page \n\n```bash\n$ touch bundles/MyOwnBundle/MyOwnBundle.js \n$ touch bundles/MyOwnBundle/router/Router.js\n$ touch bundles/MyOwnBundle/controller/MyOwnController.js\n$ touch bundles/MyOwnBundle/views/pages/my-private-tab.ejs\n$ touch bundles/MyOwnBundle/views/pages/my-public-tab.ejs\n```\n* Step 4: We are now going to create the public and the private template pages\n  \n  * Step 4.1: Edit the `my-public-tab.ejs` template as followed\n  ```html\n  \u003c% include partials/head %\u003e\n  \u003c% include partials/header %\u003e\n  \n  \u003cdiv class=\"container\"\u003e\n  \t\u003cdiv id=\"content\"\u003e\n  \t\t\u003ch1\u003eThis is a public page\u003c/h1\u003e\n  \t\t\u003chr\u003e\n  \t\t\u003cp\u003eYou don't need to register to see this !\u003c/p\u003e\n  \t\u003c/div\u003e\n  \u003c/div\u003e\n  \t\t\n  \u003c% include partials/footer %\u003e\n  \u003c% include partials/end %\u003e\n  ```\n  We use here the `include` mechanism of [EJS](http://ejs.co/) to import the headers and footers of the page.\n  \n  * Step 4.2: Edit the `my-private-tab.ejs` template\n  ```html\n  \u003c% include partials/head %\u003e\n  \u003c% include partials/header %\u003e\n  \n  \u003cdiv class=\"container\"\u003e\n  \t\u003cdiv id=\"content\"\u003e\n  \t\t\u003ch1\u003eThis is a private page\u003c/h1\u003e\n  \t\t\u003chr\u003e\n  \t\t\u003cp\u003eYou need to be registered to see this !\u003c/p\u003e\n  \t\u003c/div\u003e\n  \u003c/div\u003e\n  \t\t\n  \u003c% include partials/footer %\u003e\n  \u003c% include partials/end %\u003e\n  ```\n  We do the same for the private page.\n\n* Step 5: Edit the controller `MyOwnController.js` that will return those templates we just created\n\n```javascript\nexports.getMyPrivateTab = function (req, res){\n    res.render('pages/my-private-tab.ejs', { user: req.user });\n};\n\nexports.getMyPublicTab = function (req, res){\n    res.render('pages/my-public-tab.ejs', {csrfToken: req.csrfToken() });\n};\n```\nFor the public page, you need to include a crsfToken to enable the different forms present on the page for unconnected users.\n\n* Step 6: Edit the router `Router.js` that will serve those 2 pages\n\n```javascript\nconst MyOwnControler = require(\"../controller/MyOwnController.js\");\nconst proxy = require('connect-ensure-login');\n\nexports.init = function(app) {\n\n    app.get('/myprivatetab', proxy.ensureLoggedIn(),function(req, res){\n        MyOwnControler.getMyPrivateTab(req, res);\n    });\n    \n    app.get('/mypublictab', function(req, res) {\n        MyOwnControler.getMyPublicTab(req, res);\n    });\n};\n```\n\nFor the private page, add the `proxy.ensureLoggedIn()` middleware to ensure that the user is logged in to access this page. By taping `yourwebsite.com/mypublictab` a user will acces the public page you just created.\n\n* Step 7: Edit the `./bundles/MainBundle/views/partials/header.ejs` file to add some buttons on the header nav-bar redirecting to those 2 pages \nAdd the following on line 14 :\n\n```html\n\u003cli\u003e\u003ca href=\"/mypublictab\"\u003eMy public tab\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"/myprivatetab\"\u003eMy private tab\u003c/a\u003e\u003c/li\u003e\n```\n\n* Step 8: Edit the bundle launcher `MyOwnController.js` to init the rooter\n\n```javascript\nconst Router = require('./router/Router');\n\nexports.init = function(app) {\n    //Launch router\n    Router.init(app);\n};\n```\n* Step 9: configure the `app.js` file to integrate your new bundle\n\nImport the bundle line 10:\n```javascript\nconst myOwnBundle = require('./bundles/MyOwnBundle/MyOwnBundle');\n```\nInit the bundle line 37:\n```javascript\nmyOwnBundle.init(app);\n```\nAdd its view folder in the EJS repository line 43:\n```javascript\n  path.join(__dirname+'/bundles/MyOwnBundle', 'views')\n\n```\nThis example bundle is already included in the actual Nusid repository. Feel free to delete it or modify it!\n\n## Adapt NUSID\n\n* How to modify the general design\n\n  You can modify the design and appearance of Nusid by modifying the style sheet located in `./client/css/style.css` and also the different partial templates present in all the pages. Those are located in the MainBundle : `./bundles/MainBundle/views/partials`. \n  * `head.ejs` for the metadata and Javascript/CSS Style sheets imports\n  * `hearder.ejs` for the menu nav-bar of the page\n  * `footer.ejs` for the footer of the page\n  * `end.ejs` for the page closing, contains others Javascript/CSS Style sheets imports\n  * `alerts.ejs` for the flash messenger.\n\n* How to modify the client-side input form validation\n\n  The client-side input form validation use 2 different technologies : [AngularJS](https://angularjs.org/) and [Browserify](http://browserify.org/).\n\n  You will find the Angular input validation animations in the form templates located here: `./bundles/UserspaceBundle/views/forms` and its Javascript code in this file : `./client/js/app.js`.\n\n  Thanks to [Browserify](http://browserify.org/) the Angular Javascript code in `app.js` can use the `require` function and import the input validation rules from the server located in `./bundles/UserspaceBundle/service/forms`. It means that the same code validate the inputs client and server side.\n\n  If you want to modify the code in `app.js` you will have to [install browserify](http://browserify.org/#install) which provide this `require` function.\n  **!!Warning!!** Every time you modify this code you will have to run the following command in a terminal :\n\n  ```bash\n  $ browserify client/js/app.js -o client/js/app-browserified.js\n  ```\n  The web pages will indeed import the `app-browserified.js` file which will convert the require imports into something the browser can read.\n\n* How to change the input validation rules\n  \n  You can change the input validation rules by editing the validation callbacks located in `./bundles/UserspaceBundle/service/forms/callbacks/ValidationCallbacks.js`. Those functions have to return an object with 2 properties :\n  * `hasError`: if the input has an error\n  * `errorMsg`: the error message to display to the user if `hasError` is `true`\n\n* How to change the general behavior of the UserspaceBundle\n\n  You have to modify the different controllers located in `./bundles/UserspaceBundle/controller` and also its user model `./bundles/UserspaceBundle/model/UserModel.js`. Feel free to contact me if you need any information.\n\n## Security Issues\n\nIf you discover a security vulnerability or a bug please contact me.\n\n## Philosophy\n\nNUSID wish to give you a starting point into your [Node.js](https://nodejs.org/en/) project with a complete user space and also a framework. This app is architectured in bundles, similarly as in the PHP framework [Symfony](https://symfony.com/). Feel free to adapt/modify the present bundles to make them fit your needs and simply add your own bundles as shown above.\n\n## Want to contribute\n\nIf you want to share some improvements, contact me and I will add you as a contributor.\n\n## License\n\n[MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/express.svg\n[npm-url]: https://npmjs.org/package/express\n[downloads-image]: https://img.shields.io/npm/dm/express.svg\n[downloads-url]: https://npmjs.org/package/express\n[travis-image]: https://img.shields.io/travis/expressjs/express/master.svg?label=linux\n[travis-url]: https://github.com/jrebecchi/NUSID\n[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/express/master.svg?label=windows\n[appveyor-url]: https://ci.appveyor.com/project/dougwilson/express\n[coveralls-image]: https://img.shields.io/coveralls/expressjs/express/master.svg\n[coveralls-url]: https://coveralls.io/r/expressjs/express?branch=master\n[gratipay-image-visionmedia]: https://img.shields.io/gratipay/visionmedia.svg\n[gratipay-url-visionmedia]: https://gratipay.com/visionmedia/\n[gratipay-image-dougwilson]: https://img.shields.io/gratipay/dougwilson.svg\n[gratipay-url-dougwilson]: https://gratipay.com/dougwilson/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrebecchi%2Fnusid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjrebecchi%2Fnusid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjrebecchi%2Fnusid/lists"}