Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/drschwabe/couch-party

A set of functions for building Couch/PouchDB driven multi-user apps
https://github.com/drschwabe/couch-party

Last synced: about 1 month ago
JSON representation

A set of functions for building Couch/PouchDB driven multi-user apps

Awesome Lists containing this project

README

        

## Couch Party

ALPHA / WIP

A set of functions for building Couch/PouchDB driven multi-user apps. Currently does basic login, registration, password reset and user profile syncing.

```
npm install couch-party
```

### Party time

```
//Login
var baseCouchURL = 'http://admin:admin@localhost:5984/myProject'
var login = {
nickOrEmail: "Sarah",
password: 'w00t'
}
couchParty.login(baseCouchURL, login, function(err, doc) {
if(err) console.log('You were not invited!')
else console.log('Welcome to the party yo!')
})
```

```
//Register
var form = {
nickname: 'Sarah',
email : '[email protected]',
password : 'w00t'
}
couchParty.register(baseCouchURL, form, function(err, couchRes) {
if(err) console.log(err)
else console.log('User created with doc._id of: ' couchRes.id)
})
```

### Sync time

There is also a function to sync client-side changes with help from PouchDB:

```
//server.js
couchParty.syncEverybody(baseCouchURL)
```

Each user gets their own database. In addition, a single 'mother' database is used for authentication. syncEverybody function keeps changes from the individual user databases to the mother.

On client side, now you can just save stuff to a browser PouchDB and let it's sync feature take care of the rest.

```
//app.js (browser)
//First, get the user doc by logging in:
var userDoc
$.post('http://localhost:4500/login', form, function(userDoc) {
//^ Assuming your server app is listening on 4500, and calls "couchParty.login" with the route above.
initPouch(userDoc)
}, 'json')

//Create a database based on the userDoc we got from server:
function initPouch(userDoc) {
var db = new PouchDB('myproject_user')
db.post(userDoc, function(err, res) {
//Now perform a live sync:
db.sync('http://admin:admin@localhost:5984/' + userDoc.db_name, { live: true, retry: true })
.on('change', function(info) {
console.log('Now this is a party!')
})
})
}
```

### Lost keys

To reset a password, first call couchParty.resetToken to generate and 'seed' the appropriate user with a secret token (then an implied step where you email the user said token) and then call couchParty.resetPass with the token and new password.

There is no built-in email mecahnism, you can send the email however you like. For example with nodemailer as in the example below.

```
//Post route from a page that collects an email address for the purpose of password reset...
//(app is an express app)
app.post('/api/reset', function(req, res) {
console.log('A visitor has requested to reset password for: ' + req.body.email)
//Lookup the username based on the email provided...
couchParty.resetToken(baseCouchURL, req.body.email, function(err, token) {
if(err) return res.send({ok:false, msg: err})
//the link contains a secret token
//the secret token is applied to the userDoc in the user database
//Now you can send the email however you like:
var email = {
to: req.body.email,
subject:`Password Reset`,
from : '[email protected]',
html: `

Hello there,


There has been a request to reset your password. If you wish to proceed, click the link below:


www.worlddomination.com/reset-confirm/token


If for any reason you did not request a password reset please reply back to inform [email protected]
`
}
//Send the mail:
//(nodemailer object initialized already)
nodemailer.sendMail(email, function(err, nodemailerRes){
if(err) return console.log(err.message)
var resultMsg = 'An email with further instruction has been sent to : ' + req.body.email
res.send({ok:true, msg: resultMsg })
})
})
})

//Post route that contains the token; this is hit after the user lands on the URL
//provided in the reset email.
app.post('/api/reset/:secretToken', function(req, res) {
couchParty.resetPass(baseCouchURL, req.params.secretToken, req.body.new_password, function(err) {
if(err) return res.send({ok:false, msg: err })
//If there was no error, the password was reset successfully:
res.send({ok:true, msg: 'Password was reset successfully.'})
})
})
```

## API

**register**
`couchParty.register(baseURL, login, callback)`
Registers a new user, accepting either a username/email or both and a password. The password is hashed before saving into the database.

```javascript
couchParty.register('http://localhost:5984/wedding_', { email: '[email protected]', password : '6969booyeah' }, (err, signupToken) => {
//signupToken = { signup_token : 'ba1b581b3318ff102bca0fc69ae688' }
//now you can send an email to the user with this token for verification
})
```

**verify**
`couchParty.verify(baseURL, signupToken, callback)`
Finds the user who matches the supplied token and marks that user's doc as { verified : true }
Returns an err if no match (or db problem) or the updated user doc if successful.

```javascript
couchParty.verify('http://localhost:5984/wedding_', { token : 'ba1b581b3318ff10' }, (err, userDoc) => {
//userDoc = { email: '[email protected]', password : 'afsadfaasdlkj33', verified : true }
})
```