3.8.7 โ€ข Published 8 years ago

@hoodie/account-server-api v3.8.7

Weekly downloads
43
License
Apache-2.0
Repository
github
Last release
8 years ago

hoodie-account-server-api

Account JavaScript API backed by PouchDB

Build Status Coverage Status Dependency Status devDependency Status

@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

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: 'pat@example.com'
  }
}

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: 'pat@example.com'
    // 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: 'pat@example.com'
  }
}, {
  id: 'session456',
  account: {
    id: 'account789',
    username: 'sam@example.com'
  }
}]

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: 'pat@example.com'
  }
}

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: 'pat@example.com'
  }
}, {
  id: 'session456',
  account: {
    id: 'account789',
    username: 'sam@example.com'
  }
}]

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: 'pat@example.com'
})

Resolves with

{
  id: 'request123',
  type: 'passwordreset',
  email: 'pat@example.com'
}

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: 'pat@example.com'})
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": "pat@example.com",
  "createdAt": "2016-01-01T00:00:00.000Z"
}

Rejects with:

Example

admin.account({username: 'pat@example.com'}).account.tokens.add({
  type: 'passwordreset',
  email: 'pat@example.com'
})

api.account().tokens.find()

admin.account(idOrObject).tokens.find(id)

resolves with tokenProperties

{
  "id": "token123",
  "type": "passwordreset",
  "accountId": "account123",
  "contact": "pat@example.com",
  "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": "pat@example.com",
  "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": "pat@example.com",
  "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 roleNames

["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

License

Apache 2.0

3.8.7

8 years ago

3.8.6

8 years ago

3.8.5

9 years ago

3.8.4

9 years ago

3.8.3

9 years ago

3.8.2

9 years ago

3.8.1

9 years ago

3.8.0

9 years ago

3.7.1

9 years ago

3.7.0

9 years ago

3.6.5

9 years ago

3.6.4

9 years ago

3.6.3

9 years ago

3.6.2

9 years ago

3.6.1

9 years ago

3.6.0

9 years ago

3.5.0

9 years ago

3.4.0

9 years ago

3.3.3

9 years ago

3.3.2

10 years ago

3.3.1

10 years ago

3.3.0

10 years ago

3.2.1

10 years ago

3.2.0

10 years ago

3.1.0

10 years ago

3.0.4

10 years ago

3.0.3

10 years ago

3.0.2

10 years ago

3.0.1

10 years ago

3.0.0

10 years ago

2.2.0

10 years ago

2.1.1

10 years ago

2.1.0

10 years ago

2.0.0

10 years ago

1.0.0

10 years ago