jcoglan / restore

Simple remoteStorage server written in Node.js
293 stars 27 forks source link

reStore Build Status

CAVEAT EMPTOR

Although it may have been published to the npm repo, this project is still considered experimental. It has not been widely deployed, and I am in the process of rolling it out for personal use and within my company.

As with any alpha-stage storage technology, you MUST expect that it will eat your data and take precautions against this. You SHOULD expect that its APIs and storage schemas will change before it is labelled stable. I MAY respond to bug reports but you MUST NOT expect that I will.

Per the MIT license, usage is entirely at your own risk.

What is this?

reStore RemoteStorage server written for Node.js. It is designed to be compatible with RemoteStorage.js from version 0.6 onwards, covering versions RemoteStorage-2011.10, RemoteStorage-2012.04, and draft-dejong of the protocol.

Installation

$ npm install restore

Usage

The following Node script will run a basic server:

process.umask(077);

var reStore = require('restore'),
    store   = new reStore.FileTree({path: 'path/to/storage'}),

    server  = new reStore({
                store:  store,
                http:   {host: '127.0.0.1', port: 8000}
              });

server.boot();

The host option is optional and specifies the hostname the server will listen on. Its default value is 0.0.0.0, meaning it will listen on all interfaces.

The server does not allow users to sign up, out of the box. If you need to allow that, use the allow.signup option:

var server = new reStore({
               store: store,
               http:  {host: '127.0.0.1', port: 8000},
               allow: {signup: true}
             });

If you navigate to http://localhost:8000/ you should then see a sign-up link in the navigation.

Storage security

In production, we recommend that you restrict access to the files managed by your reStore server as much as possible. This is particularly true if you host your storage on a machine with other web applications; you need to protect your files in the event that one of those apps is exploited.

You should take these steps to keep your storage safe:

If you're using the Redis backend, apply similar access restrictions to the database and to any files containing the database access credentials.

Serving over HTTPS

Since RemoteStorage is a system for storing arbitrary user-specific data, and since it makes use of OAuth 2.0, we recommend you serve it over a secure connection. You can boot the server to listen for HTTP or HTTPS requests or both. This configuration boots the app on two ports, one secure and one plaintext:

var server = new reStore({
  store:  store,
  http:   {
    host: '127.0.0.1',
    port: 8000
  },
  https:  {
    force:  true,
    host:   '127.0.0.1',
    port:   4343,
    key:    'path/to/ssl.key',
    cert:   'path/to/ssl.crt',
    ca:     'path/to/ca.pem'    // optional
  }
});

server.boot();

Note that you should not run reStore as root. To make it available via port 80 or 443, use Apache, nginx or another reverse proxy.

The force: true line in the https section means the app will:

reStore considers a request to be secure if:

So you can have an SSL-terminating proxy in front of reStore as long as it sets one of those headers, and does not let external clients set them. In this setup, you can set https.force = true but omit https.port; this means reStore itself will not accept encrypted connections but will apply the above behaviour to enforce secure connections.

Storage backends

reStore supports pluggable storage backends, and comes with two implementations out of the box:

All the backends support the same set of features, including the ability to store arbitrary binary data with content types and modification times.

They are configured as follows:

// To use the file tree store:
var store = new reStore.FileTree({path: 'path/to/storage'});

// To use the Redis store:
var store = new reStore.Redis({
  host:     'redis.example.com',    // default is 'localhost'
  port:     1234,                   // default is 6379
  database: 2,                      // default is 0
  password: 'unhosted'              // default is no password
});

// Then create the server with your store:
var server = new reStore({
                store:  store,
                http:   {port: process.argv[2]}
              });

server.boot();

License

(The MIT License)

Copyright (c) 2012-2015 James Coglan

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.