@hoodie/account-server-api
v3.8.7
Published
Account JavaScript API backed by PouchDB
Downloads
156
Readme
hoodie-account-server-api
Account JavaScript API backed by PouchDB
@hoodie/account-server-api
is a JavaScript API to manage user accounts and
authentication backed by PouchDB. Features include account profiles and tokens.
Example
var AccountApi = require('@hoodie/account-server-api')
var PouchDB = require('pouchdb')
var api = new AccountApi({
PouchDB: PouchDB,
usersDb: 'my-users-db',
secret: 'secret123'
})
API
@hoodie/account-server-api
is a subset of hoodie-account-client/admin.
If you see any inconsistencies, please create an issue
- Constructor
- api.sessions.add()
- api.sessions.find()
- api.sessions.findAll()
- api.sessions.remove()
- api.sessions.removeAll()
- api.accounts.add()
- api.accounts.find()
- api.accounts.findAll()
- api.accounts.update()
- api.accounts.updateAll()
- api.accounts.remove()
- api.accounts.removeAll()
- api.requests.add()
- api.requests.find()
- api.requests.findAll()
- api.requests.remove()
- api.requests.removeAll()
- api.account()
- api.account().profile.find()
- api.account().profile.update()
- api.account().tokens.add()
- api.account().tokens.find()
- api.account().tokens.findAll()
- api.account().tokens.remove()
- api.account().roles.add()
- api.account().roles.findAll()
- api.account().roles.remove()
- Events
Constructor
new AccountApi(options)
Returns an api
instance.
Examples
var PouchDB = require('pouchdb')
var api = new AccountApi({
PouchDB: PouchDB,
secret: 'secret123',
usersDb: 'my-users-db'
})
api.sessions.add()
Admins can create a session for any user.
admin.sessions.add(options)
Resolves with sessionProperties
{
id: 'session123',
// account is always included
account: {
id: 'account456',
username: '[email protected]'
}
}
Rejects with:
Examples
// create session if pat’s password is "secret"
admin.sessions.add({
account: {
username: 'pat',
password: 'secret'
}
}).then(function (sessionProperties) {
var sessionId = sessionProperties.id
var username = sessionProperties.account.username
}).catch(function (error) {
console.error(error)
})
// create session for pat
admin.sessions.add({
account: {
username: 'pat'
}
}).then(function (sessionProperties) {
var sessionId = sessionProperties.id
var username = sessionProperties.account.username
}).catch(function (error) {
console.error(error)
})
// create session using a one-time auth token
admin.sessions.add({
account: {
token: 'secrettoken123'
}
}).then(function (sessionProperties) {
var sessionId = sessionProperties.id
var username = sessionProperties.account.username
}).catch(function (error) {
console.error(error)
})
api.sessions.find()
admin.sessions.find(sessionId)
Resolves with sessionProperties
{
id: 'session123',
// account is always included
account: {
id: 'account456',
username: '[email protected]'
// admin accounts have no profile
}
}
Rejects with:
Example
admin.sessions.find('abc4567').then(function (sessionProperties) {
console.log('Session is valid.')
}).catch(function (error) {
if (error.name === 'NotFoundError') {
console.log('Session is invalid')
return
}
console.error(error)
})
api.sessions.findAll()
🐕 TO BE DONE: #27
admin.sessions.findAll(options)
Resolves with Array of sessionProperties
[{
id: 'session123',
account: {
id: 'account456',
username: '[email protected]'
}
}, {
id: 'session456',
account: {
id: 'account789',
username: '[email protected]'
}
}]
Rejects with:
Example
admin.sessions.findAll()
.then(function (sessions) {})
.catch(function (error) {
console.error(error)
})
api.sessions.remove()
admin.sessions.remove(sessionId)
Resolves with sessionProperties
{
id: 'session123',
account: {
id: 'account456',
username: '[email protected]'
}
}
Rejects with:
Example
admin.sessions.remove('abc4567')
.then(function (sessionProperties) {})
.catch(function (error) {
console.error(error)
})
NOTE: #27 Deleting a Session does not really have an effect today, as no session state is kept, and sessions are hash based
api.sessions.removeAll()
🐕 TO BE DONE: #27
admin.sessions.removeAll(options)
Resolves with Array of sessionProperties
[{
id: 'session123',
account: {
id: 'account456',
username: '[email protected]'
}
}, {
id: 'session456',
account: {
id: 'account789',
username: '[email protected]'
}
}]
Rejects with:
Example
admin.sessions.removeAll()
.then(function (sessions) {})
.catch(function (error) {
if (error.name === 'NotFoundError') {
console.log('Session is invalid')
return
}
console.error(error)
})
api.accounts.add()
admin.accounts.add(object)
Resolves with accountProperties
:
{
"id": "account123",
"username": "pat",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-01-01T00:00:00.000Z",
"profile": {
"fullname": "Dr. Pat Hook"
}
}
Rejects with:
Example
admin.accounts.add({
username: 'pat',
password: 'secret',
profile: {
fullname: 'Dr Pat Hook'
}
})
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
api.accounts.find()
An account can be looked up by account.id, username or token.
- If a
username
property is present, it will be looked up by username - If an
id
property is present, it will be looked up by accountId - If an
token
property is present, it will be looked up by token
admin.accounts.find(idOrObject, options)
Resolves with accountProperties
:
{
"id": "account123",
"username": "pat",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-01-01T00:00:00.000Z",
// if options.include === 'profile'
"profile": {
"fullname": "Dr. Pat Hook"
}
}
Rejects with:
Example
admin.accounts.find({ username: 'pat' })
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
api.accounts.findAll()
admin.accounts.findAll(options)
Resolves with Array of accountProperties
[{
"id": "account123",
"username": "pat",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-01-01T00:00:00.000Z",
// if options.include === 'profile'
"profile": {
"fullname": "Dr. Pat Hook"
}
}, {
"id": "account456",
"username": "sam",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-01-01T00:00:00.000Z",
// if options.include === 'profile'
"profile": {
"fullname": "Lady Samident"
}
}]
Rejects with:
Example
admin.accounts.findAll()
.then(function (accounts) {})
.catch(function (error) {
console.error(error)
})
api.accounts.update()
An account can be looked up by account.id, username or token.
- If a
username
property is present, it will be looked up by username - If an
id
property is present, it will be looked up by accountId - If an
token
property is present, it will be looked up by token
admin.accounts.update(idOrObject, changedProperties, options)
// or
admin.accounts.update(accountProperties, options)
Resolves with accountProperties
:
{
"id": "account123",
"username": "pat",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-01-01T00:00:00.000Z",
// if options.include === 'profile'
"profile": {
"fullname": "Dr. Pat Hook"
}
}
Rejects with:
Examples
admin.accounts.update({ username: 'pat' }, { foo: 'bar' })
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
// same as
admin.accounts.update({ username: 'pat', foo: 'bar' })
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
api.accounts.updateAll()
🐕 TO BE DONE: create issue and link it here
api.accounts.remove()
An account can be looked up by account.id, username or token.
- If a
username
property is present, it will be looked up by username - If an
id
property is present, it will be looked up by accountId - If an
token
property is present, it will be looked up by token
admin.accounts.remove(idOrObject, changedProperties, options)
// or
admin.accounts.remove(accountProperties, options)
Resolves with accountProperties
:
{
"id": "account123",
"username": "pat",
"createdAt": "2016-01-01T00:00:00.000Z",
"updatedAt": "2016-02-01T00:00:00.000Z",
"deletedAt": "2016-03-01T00:00:00.000Z",
// if options.include === 'profile'
"profile": {
"fullname": "Dr. Pat Hook"
}
}
Rejects with:
Examples
admin.accounts.remove({ username: 'pat' }, { reason: 'foo bar' })
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
// same as
admin.accounts.remove({ username: 'pat', reason: 'foo bar' })
.then(function (accountProperties) {})
.catch(function (error) {
console.error(error)
})
api.accounts.removeAll()
🐕 TO BE DONE: create issue and link it here
api.requests.add()
🐕 TO BE DONE: create issue and link it here
admin.requests.add({
type: 'passwordreset',
email: '[email protected]'
})
Resolves with
{
id: 'request123',
type: 'passwordreset',
email: '[email protected]'
}
api.requests.find()
🐕 TO BE DONE: create issue and link it here
admin.requests.find('token123')
admin.requests.find({id: 'token123'})
api.requests.findAll()
🐕 TO BE DONE: create issue and link it here
admin.requests.findAll()
api.requests.remove()
🐕 TO BE DONE: create issue and link it here
admin.requests.remove('token123')
admin.requests.find({id: 'token123'})
api.requests.removeAll()
🐕 TO BE DONE: create issue and link it here
api.account()
The admin.account
method returns a scoped API for one account, see below
var account = admin.account(idOrObject)
Examples
admin.account('account123')
admin.account({id: 'account123'})
admin.account({username: '[email protected]'})
admin.account({token: 'token456'})
api.account().profile.find()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).profile.find()
resolves with profileProperties
{
"id": "account123-profile",
"fullname": "Dr Pat Hook",
"address": {
"city": "Berlin",
"street": "Adalberststraße 4a"
}
}
api.account().profile.update()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).profile.update(changedProperties)
resolves with profileProperties
{
"id": "account123-profile",
"fullname": "Dr Pat Hook",
"address": {
"city": "Berlin",
"street": "Adalberststraße 4a"
}
}
api.account().tokens.add()
admin.account('account123').tokens.add(properties)
resolves with tokenProperties
{
"id": "token123",
"type": "passwordreset",
"accountId": "account123",
"contact": "[email protected]",
"createdAt": "2016-01-01T00:00:00.000Z"
}
Rejects with:
Example
admin.account({username: '[email protected]'}).account.tokens.add({
type: 'passwordreset',
email: '[email protected]'
})
api.account().tokens.find()
admin.account(idOrObject).tokens.find(id)
resolves with tokenProperties
{
"id": "token123",
"type": "passwordreset",
"accountId": "account123",
"contact": "[email protected]",
"createdAt": "2016-01-01T00:00:00.000Z"
}
Rejects with:
Example
admin.account({username: 'pat'}).tokens.find('token123')
api.account().tokens.findAll()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).tokens.findAll(options)
resolves with array of tokenProperties
[{
"id": "token123",
"type": "passwordreset",
"accountId": "account123",
"contact": "[email protected]",
"createdAt": "2016-01-01T00:00:00.000Z"
}, {
"id": "token456",
"type": "session",
"accountId": "account123",
"createdAt": "2016-01-02T00:00:00.000Z"
}]
Example
admin.account({username: 'pat'}).tokens.findAll()
.then(function (tokens) {})
.catch(function (error) {
console.error(error)
})
api.account().tokens.remove()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).tokens.remove(idOrObject)
resolves with tokenProperties
{
"id": "token123",
"type": "passwordreset",
"accountId": "account123",
"contact": "[email protected]",
"createdAt": "2016-01-01T00:00:00.000Z"
}
Example
admin.account({username: 'pat'}).tokens.removes('token123')
api.account().roles.add()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).roles.add(name)
resolves with roleName
"mycustomrole"
Example
admin.account({username: 'pat'}).roles.add('mycustomrole')
api.account().roles.findAll()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).roles.add(name)
resolves with array of roleName
s
["mycustomrole", "myothercustomrole"]
Example
admin.account({username: 'pat'}).roles.findAll()
.then(function (roles) {})
.catch(function (error) {
console.error(error)
})
api.account().roles.remove()
🐕 TO BE DONE: create issue and link it here
admin.account(idOrObject).roles.remove(name)
resolves with roleName
"mycustomrole"
Example
admin.account({username: 'pat'}).roles.remove('mycustomrole')
Events
🐕 TO BE DONE: #35
Events emitted on
admin.sessions
admin.accounts
admin.requests
admin.sessions.on('change', function (eventName, session) {})
admin.accounts.on('update', function (account) {})
admin.requests.on('remove', handler)
Contributing
Have a look at the Hoodie project's contribution guidelines. If you want to hang out you can join our Hoodie Community Chat.
Testing
Local setup
git clone https://github.com/hoodiehq/hoodie-account-server-api.git
cd hoodie-account-server-api
npm install
Run all tests and code style checks
npm test
If you want to run a single test you can do it with
./node_modules/.bin/tap test/unit/sessions/remove-test.js