@userdashboard/dashboard

Dashboard for building web apps and SaaS


Keywords
dashboard, saas, webapp, organizations, stripe-subscriptions, webapplication, stripe-connect, saas-boilerplate, saas-admin
License
MIT
Install
npm install @userdashboard/dashboard@1.0.392

Documentation

Dashboard

StandardJS Test suite Test suite Test suite Test suite

When you want to write a web app you have to create authentication and account management and lots of other stuff each time. Dashboard bundles all of this repeatative boilerplate into a parallel web server so your web app has fewer responsibilities.

After you set up a copy of Dashboard server you have a complete user and administrator interface with all the basic user functionality like registering and changing passwords provided by Dashboard.

Then you write your application server using your preferred language and have it serve your guest landing page on / and your application on /home, and any other URLs your application needs.

Users browse your dashboard server's address and it may serve its own content or proxy your application server. Dashboard tells your server who the user is and you can access more information through APIs. Your content can occupy the entire page or be served within a generic template with header, navigation bar and content sections. You can make your own template too and serve CSS to style Dashboard's content.

Dashboard is written in NodeJS and supports local file system, Redis, PostgreSQL and S3 for data storage. Dashboard modules are distributed using NPM and their src/www folders get merged to add UI and API routes. There is test coverage for all UI and API routes and the UI is documented with screenshots at multiple resolutions.

The Organizations module adds a complete invitation-based membership system for your users. The Stripe Connect module adds a complete custom integration ready for your users to receive payouts. The Stripe Subscriptions module adds everything you need to start a Subscription SaaS.

Support and contributions

If you have encountered a problem post an issue on the appropriate Github repository.

If you would like to contribute check Github Issues for ways you can help.

For help using or contributing to this software join the freenode IRC #dashboard chatroom - Web IRC client.

Documentation

Dashboard and modules have setup and usage documentation contained in readme.md files. This is the Dashboard readme.md.

Dashboard has run-time documentation generated when the server starts:

  • api.txt provides a local copy of usage information for all of your API endpoints

  • sitemap.txt contains your configuration, all URLs and where they have come from

The readme.md files are published in the online documentation too. Online API documentation has more information than the api.txt files. The UI documentation for users and administrators demonstrates how to browse to or use each page.

Write your application server

Your application server needs to serve a guest landing page on / and a /home page for your users, and any other URLs you want. When your server is ready you can open your Dashboard server at http://localhost:8000. The Dashboard server will communicate with your application server whenever the user requests a URL it doesn't recognize. The first account to register is the website owner with the unique authority to assign and revoke administrators. To allow guest access and use the entire page your / page should specify <html auth="false" template="false">.

Content is served in an iframe within the template.html unless you set template="false" in your <html> tag. Everything outside of /public is considered private unless you set auth="false" in your <html> tag.

Style the Dashboard content like your application

Your application server can serve two special CSS files, /public/template-additional.css and /public/content-additional.css to theme the Dashboard server template and content. If you do not provide these files your Dashboard server will respond with blank files rather than 404 errors.

The content you serve can include a <template id="head"></template> with HTML you wish to be copied into the template's <HEAD> tag. Provide a <template id="navbar"></template> with HTML links if you want to borrow the template's navigation bar.

Accessing Dashboard and module APIs from your application server

Dashboard and official modules are completely API-driven and you can access the same APIs on behalf of the user making requests. You perform GET, POST, PATCH, and DELETE HTTP requests against the API endpoints to fetch or modify data. This example uses NodeJS to fetch the user's account from the Dashboard server.

const account = await proxy(`/api/user/account?accountid=${accountid}`, accountid, sessionid)

const proxy = util.promisify((path, accountid, sessionid, callback) => {
    let hashText
    if (accountid) {
        hashText = `${process.env.APPLICATION_SERVER_TOKEN}/${accountid}/${sessionid}`
    } else {
        hashText = process.env.APPLICATION_SERVER_TOKEN
    }
    const salt = bcrypt.genSaltSync(4)
    const token = bcrypt.hashSync(hashText, salt)
    const requestOptions = {
        host: 'dashboard.example.com',
        path: path,
        port: '443',
        method: 'GET',
        headers: {
            'x-application-server': 'application.example.com',
            'x-dashboard-token': token
        }
    }
    if (accountid) {
        requestOptions.headers['x-accountid'] = accountid
        requestOptions.headers['x-sessionid'] = sessionid
    }
    const proxyRequest = require('https').request(requestOptions, (proxyResponse) => {
        let body = ''
        proxyResponse.on('data', (chunk) => {
            body += chunk
        })
        return proxyResponse.on('end', () => {
            return callback(null, JSON.parse(body))
        })
    })
    proxyRequest.on('error', (error) => {
        return callback(error)
    })
    return proxyRequest.end()
  })
}

Set up a copy of Dashboard

Dashboard is self-hosted and open source, you need to deploy it to eg Heroku or Digital Ocean or AWS before you can use it. Dashboard is a NodeJS project requiring node 12.13.1.

$ mkdir dashboard-server
$ cd dashboard-server
$ npm init
$ npm install @userdashboard/dashboard
# install any modules you want here
$ echo "require('@userdashboard/dashboard').start(__dirname)" > main.js

Which storage backend?

Dashboard by default uses local disk, this is good for development and okay for applications that aren't going to grow to many users. Alternatively you can use Redis, PostgreSQL or S3-compatible backends.

Name Description Package Repository
Redis Very fast but expensive to scale @userdashboard/storage-redis github
Amazon S3 Slow but cheap to scale @userdashboard/storage-s3 github
PostgreSQL Fast but not cheap to scale @userdashboard/storage-postgresql github

Which modules?

Modules add new pages and API routes for additional functionality. Modules are NodeJS packages that you install with NPM:

$ npm install @userdashboard/stripe-subscriptions

You need to notify Dashboard which modules you are using in package.json conffiguration:

"dashboard": {
  "modules": [
    "@userdashboard/stripe-subscriptions"
  ]
}
Name Description Package Repository
MaxMind GeoIP IP address-based geolocation @userdashboard/maxmind-geoip github
Organizations User created groups @userdashboard/organizations github
Stripe Subscriptions SaaS functionality @userdashboard/stripe-subscriptions github
Stripe Connect Marketplace functionality @userdashboard/stripe-connect github

If you have built your own modules you may submit a pull request to add them to this list.

What user registration information

Dashboard supports optionally collecting a variety of profile information at registration. This requires setting two environment variables:

   REQUIRE_PROFILE=true
   USER_PROFILE_FIELDS="any,of,the,below"

Otherwise users may register with just a username and password, both of which are encrypted so they cannot be used for anything but signing in.

Field
full-name
contact-email
display-name
display-email
dob
location
phone
company-name
website
occupation

Publishing your Dashboard server

Dashboard is a stateless NodeJS server, you can publish it to Heroku or similar PaaS or put it on virtual machines through web hosts like Digital Ocean and Vultr.

Securing communication between your Dashboard and application server

When you have published your server the communication between it and your application should take place over HTTPS and you should verify the requests. When Dashboard proxies your application server it includes header information about the user:

x-accountid
x-sessionid
x-dashboard-server
x-dashboard-token

The x-dashboard-token is a bcrypt hash derived from user information and a secret shared between your dashboard and application servers. This is a NodeJS example of validating the request:

function compareDashboardHash(req, callback) {
    if (!req.headers['x-dashboard-server']) {
        return callback(null, req)
    }
    if (req.headers['x-dashboard-server'] !== process.env.DASHBOARD_SERVER) {
        return callback(null, req)
    }
    let expected
    if (!req.headers['x-accountid']) {
        expected = process.env.APPLICATION_SERVER_TOKEN
    } else {
        expected = `${process.env.APPLICATION_SERVER_TOKEN}/${req.headers['x-accountid']}/${req.headers['x-sessionid']}`
    }
    const sha = crypto.createHash('sha256')
    const expectedHash = sha.update(expected).digest('hex')
    return bcrypt.compare(expectedHash, req.headers['x-dashboard-token'], (error, match) => {
        if (match) {
            req.verified = true
        }
        return callback(null, req)
    })
}

Creating modules for Dashboard

Dashboard modules can provide additional APIs and content integrated with Dashboard when it scans the /src/www to create the sitemap. A module is a NodeJS application too.

Setting up a module project

$ mkdir my-module
$ cd my-module
$ npm install @userdashboard/dashboard
# create main.js to start the server
# create index.js optionally exporting any relevant API
# add your content or API endpoints or whatever your module is
$ npm publish

If you're adding to the APIs or the UIs these paths have special significance:

Folder Description
/src/www Web server root
/src/www/public Static assets served quickly
/src/www/account User account management pages
/src/www/account/YOUR_MODULE/ Your additions (if applicable)
/src/www/administrator Administration pages
/src/www/administrator/YOUR_MODULE/ Your additions (if applicable)
/src/www/api/user User account management pages
/src/www/api/user/YOUR_MODULE/ Your additions (if applicable)
/src/www/api/administrator Administration APIs
/src/www/api/administrator/YOUR_MODULE/ Your additions (if applicable)

Adding HTML content

Dashboard renders page content on the server-side using a DOM-like-interface and JSON-representation of the HTML. HTML files will be served as static HTML if they are not accompanied by a NodeJS handler.

Content pages may export before, get and post methods for Dashboard's server. NodeJS files can also determine if a page is wrapped in the template or requires authorization per <html template="false" auth="false" />.

{
  auth: false, // allow guest access to this page
  template: false, // occupy the full screen
  before: (req),
  get: (req, res),
  post: (req, res)
}

Adding API endpoints

Endpoints export methods for HTTP requests and do not serve responses as the API is dually-available to NodeJS and HTTP. It returns objects for use with NodeJS and converts those to JSON-responses if accessing via HTTP. API routes can be exposed for guests.

{
  auth: false, // allow guest access to this endpoint
  before: (req),
  delete: (req),
  get: (req),
  patch: (req),
  post: (req),
  put: (req)
}