@hoodie/account-client

    6.0.3 • Public • Published

    hoodie-account-client

    Account client API for the browser

    Build Status Coverage Status Dependency Status devDependency Status

    hoodie-account-client is a JavaScript client for the Account JSON API. It persists session information in localStorage (or your own store API) and provides front-end friendly APIs for things like creating a user account, confirming, resetting a password, changing profile information, or closing the account.

    Example

    // Account loaded via <script> or require('@hoodie/account-client')
    var account = new Account('https://example.com/account/api')
     
    // check if user is signed in
    account.get('session').then(function (session) {
      if (session) {
        renderDashboard()
      } else {
        renderWelcome()
      }
    })
     
    account.on('signout', redirectToHome)

    API

    Constructor

    new Account(options)
    Argument Type Description Required
    options.url String Path or full URL to root location of the account JSON API Yes
    options.id String The initial account id can be passed. Useful for apps that can be used locally without an account. Defaults to random id
    options.cacheKey String Name of localStorage key where to persist the session cache. Not used if options.cache is passed. Defaults to account
    options.cache Object Object with .get(), .set(properties) and .unset() methods to persist the account status. Each method must return a promise, .get() resolves with the account’s properties or an empty object. Defaults to a localStorage-based API, see also options.cacheKey
    options.validate Function Optional function to validate account before sending sign up / sign in / update requests No

    Returns account API.

    Example

    new Account({
      url: '/api',
      id: 'user123',
      cacheKey: 'myapp.session',
      validate: function (options) {
        if (options.username.length < 3) {
          throw new Error('Username must have at least 3 characters')
        }
      }
    })

    account.validate

    Calls the function passed into the Constructor. Returns a Promise that resolves to true by default

    account.validate(options)
    Argument Type Required
    options.username String No
    options.password String No
    options.profile Object No

    Resolves with an argument.

    Rejects with any errors thrown by the function originally passed into the Constructor.

    Example

    var account = new Account({
      url: '/api',
      cacheKey: 'app.session',
      validate: function (options) {
        if (options.password.length < 8) {
          throw new Error('password should contain at least 8 characters')
        }
      }
    })
     
    account.validate({
      username: 'DocsChicken',
      password: 'secret'
    })
     
    .then(function () {
      console.log('Successfully validated!')
    })
     
    .catch(function (error) {
      console.log(error) // should be an error about the password being too short
    })

    account.signUp

    Creates a new user account on the Hoodie server. Does not sign in the user automatically, account.signIn must be called separately.

    account.signUp(accountProperties)
    Argument Type Required
    accountProperties.username String Yes
    accountProperties.password String Yes

    Resolves with accountProperties:

    {
      "id": "account123",
      "username": "pat",
      "createdAt": "2016-01-01T00:00.000Z",
      "updatedAt": "2016-01-01T00:00.000Z"
    }

    Rejects with:

    InvalidError Username must be set
    SessionError Must sign out first
    ConflictError Username <username> already exists
    ConnectionError Could not connect to server

    Example

    account.signUp({
      username: 'pat',
      password: 'secret'
    }).then(function (accountProperties) {
      alert('Account created for ' + accountProperties.username)
    }).catch(function (error) {
      alert(error)
    })

    🐕 Implement account.signUp with profile: {...} option: #11


    account.signIn

    Creates a user session

    account.signIn(options)
    Argument Type Description Required
    options.username String - Yes
    options.password String - Yes

    Resolves with accountProperties:

    {
      "id": "account123",
      "username": "pat",
      "createdAt": "2016-01-01T00:00.000Z",
      "updatedAt": "2016-01-02T00:00.000Z",
      "profile": {
        "fullname": "Dr. Pat Hook"
      }
    }

    Rejects with:

    UnconfirmedError Account has not been confirmed yet
    UnauthorizedError Invalid Credentials
    Error A custom error set on the account object, e.g. the account could be blocked due to missing payments
    ConnectionError Could not connect to server

    Example

    account.signIn({
      username: 'pat',
      password: 'secret'
    }).then(function (sessionProperties) {
      alert('Ohaj, ' + sessionProperties.account.username)
    }).catch(function (error) {
      alert(error)
    })

    account.signOut

    Deletes the user’s session

    account.signOut()

    Resolves with sessionProperties like account.signin, but without the session id:

    {
      "account": {
        "id": "account123",
        "username": "pat",
        "createdAt": "2016-01-01T00:00.000Z",
        "updatedAt": "2016-01-02T00:00.000Z",
        "profile": {
          "fullname": "Dr. Pat Hook"
        }
      }
    }

    Rejects with:

    Error A custom error thrown in a before:signout hook

    Example

    account.signOut().then(function (sessionProperties) {
      alert('Bye, ' + sessionProperties.account.username)
    }).catch(function (error) {
      alert(error)
    })

    account.destroy

    Destroys the account of the currently signed in user.

    account.destroy()

    Resolves with sessionProperties like account.signin, but without the session id:

    {
      "account": {
        "id": "account123",
        "username": "pat",
        "createdAt": "2016-01-01T00:00.000Z",
        "updatedAt": "2016-01-02T00:00.000Z",
        "profile": {
          "fullname": "Dr. Pat Hook"
        }
      }
    }

    Rejects with:

    Error A custom error thrown in a before:destroy hook
    ConnectionError Could not connect to server

    Example

    account.destroy().then(function (sessionProperties) {
      alert('Bye, ' + sessionProperties.account.username)
    }).catch(function (error) {
      alert(error)
    })

    account.get

    Returns account properties from local cache or fetches them from remote. Fetches properties from remote unless

    1. User is signed out
    2. Only id and or session properties are requested
    3. options.local is set to true
    account.get(properties, options)
    Argument Type Description Required
    properties String or Array of strings When String, only this property gets returned. If array of strings, only passed properties get returned No
    options.local Boolean When set to true then only the properties from local cache are returned. No

    Resolves with object with account properties or value of passed path, depending on the properties argument passed

    Examples

    account.get().then(function (properties) {
      alert('You signed up at ' + properties.createdAt)
    })
    account.get('createdAt').then(function (createdAt) {
      alert('You signed up at ' + createdAt)
    })
    account.get(['username', 'createdAt']).then(function (properties) {
      alert('Hello ' + properties.username + '! You signed up at ' + properties.createdAt)
    })
    account.get({local: true}).then(function (cachedProperties) {
      // ...
    })
    account.get('session').then(function (session) {
      if (session) {
        // user is signed in
      } else {
        // user is signed out
      }
    })
    account.get('session.invalid').then(function (hasInvalidSession) {
      if (hasInvalidSession) {
        // user is signed in but has an expired or otherwise invalidated session
      }
    })

    account.update

    Update account properties on server and local cache

    account.update(changedProperties)
    Argument Type Description Required
    changedProperties Object Object of properties & values that changed. Other properties remain unchanged. No

    Resolves with accountProperties:

    {
      "id": "account123",
      "username": "pat",
      "createdAt": "2016-01-01T00:00.000Z",
      "updatedAt": "2016-01-01T00:00.000Z"
    }

    Rejects with:

    UnauthenticatedError Session is invalid
    InvalidError Custom validation error
    ConflictError Username <username> already exists
    ConnectionError Could not connect to server

    Example

    account.update({username: 'treetrunks'}).then(function (properties) {
      alert('You are now known as ' + properties.username)
    })

    account.profile.get

    Returns account properties from local cache or fetches them from remote.

    account.profile.get(properties)
    Argument Type Description Required
    properties String or Array of strings When String, only this property gets returned. If array of strings, only passed properties get returned. Property names can have `.` separators to return nested properties. No
    options.local Boolean When set to true then only the properties from local cache are returned. No

    Resolves with profile properties, falls back to empty object {}. If a single string is passed as properties then resolves with value for that property.

    Examples

    account.profile.get().then(function (properties) {
      alert('Hey there ' + properties.fullname)
    })
    account.profile.get('fullname').then(function (fullname) {
      alert('Hey there ' + fullname)
    })
    account.profile.get(['fullname', 'address.city'], {local: true}).then(function (properties) {
      alert('Hey there ' + properties.fullname + '. How is ' + properties.address.city + '?')
    })

    account.profile.update

    Update profile properties on server and local cache

    account.profile.update(changedProperties)
    Argument Type Description Required
    changedProperties Object Object of properties & values that changed. Other properties remain unchanged. No

    Resolves with profileProperties:

    {
      "id": "account123-profile",
      "fullname": "Dr Pat Hook",
      "address": {
        "city": "Berlin",
        "street": "Adalberststraße 4a"
      }
    }

    Rejects with:

    UnauthenticatedError Session is invalid
    InvalidError Custom validation error
    ConnectionError Could not connect to server

    Example

    account.profile.update({fullname: 'Prof Pat Hook'}).then(function (properties) {
      alert('Congratulations, ' + properties.fullname)
    })

    account.request

    Sends a custom request to the server, for things like password resets, account upgrades, etc.

    account.request(properties)
    Argument Type Description Required
    properties.type String Name of the request type, e.g. "passwordreset" Yes
    properties Object Additional properties for the request No

    Resolves with requestProperties:

    {
      "id": "request123",
      "type": "passwordreset",
      "contact": "pat@example.com",
      "createdAt": "2016-01-01T00:00.000Z",
      "updatedAt": "2016-01-01T00:00.000Z"
    }

    Rejects with:

    ConnectionError Could not connect to server
    NotFoundError Handler missing for "passwordreset"
    InvalidError Custom validation error

    Example

    account.request({type: 'passwordreset', contact: 'pat@example.com'}).then(function (properties) {
      alert('A password reset link was sent to ' + properties.contact)
    })

    account.on

    account.on(event, handler)

    Example

    account.on('signin', function (accountProperties) {
      alert('Hello there, ' + accountProperties.username)
    })

    account.one

    Call function once at given account event.

    account.one(event, handler)

    Example

    account.one('signin', function (accountProperties) {
      alert('Hello there, ' + accountProperties.username)
    })

    account.off

    Removes event handler that has been added before

    account.off(event, handler)

    Example

    account.off('singin', showNotification)

    Events

    Event Description Arguments
    signup New user account created successfully accountProperties with .session property
    signin Successfully signed in to an account accountProperties with .session property
    signout Successfully signed out accountProperties with .session property
    passwordreset Email with password reset token sent
    unauthenticate Server responded with "unauthenticated" when checking session
    reauthenticate Successfully signed in with the same username (useful when session has expired) accountProperties with .session property
    update Successfully updated an account's properties accountProperties with .session property

    Hooks

    // clear user’s local store signin and after signout
    account.hook.before('signin', function (options) {
      return localUserStore.clear()
    })
    account.hook.after('signout', function (options) {
      return localUserStore.clear()
    })
    Hook Arguments
    signin options as they were passed into account.signIn(options)
    signout {}

    See before-after-hook for more information.

    Requests

    Hoodie comes with a list of built-in account requests, which can be disabled, overwritten or extended in hoodie-account-server

    When a request succeeds, an event with the same name as the request type gets emitted. For example, account.request({type: 'passwordreset', contact: 'pat@example.com') triggers a passwordreset event, with the requestProperties passed as argument.

    passwordreset Request a password reset token

    Testing

    Local setup

    git clone https://github.com/hoodiehq/hoodie-account-client.git
    cd hoodie-account-client
    npm install
    

    In Node.js

    Run all tests and validate JavaScript Code Style using standard

    npm test
    

    To run only the tests

    npm run test:node
    

    To test hoodie-account-client in a browser you can link it into hoodie-account, which provides a dev-server:

    git clone https://github.com/hoodiehq/hoodie-account.git
    cd hoodie-account
    npm install
    npm link /path/to/hoodie-account-client
    npm start
    

    hoodie-account bundles hoodie-account-client on npm start, so you need to restart hoodie-account to see your changes.

    Contributing

    Have a look at the Hoodie project's contribution guidelines. If you want to hang out you can join our Hoodie Community Chat.

    License

    Apache 2.0

    Install

    npm i @hoodie/account-client

    DownloadsWeekly Downloads

    24

    Version

    6.0.3

    License

    Apache-2.0

    Last publish

    Collaborators

    • hoodie