Skip to content

Commit

Permalink
feat: Hooks
Browse files Browse the repository at this point in the history
BREAKING CHANGE:

The `pre:*` and `post:*` events introduced in #65 have now been removed in favor of a proper `account.hook.{before,after}` API. See https://github.com/hoodiehq/hoodie-account-client#hooks for more details.

This is not technically a breaking change as the `pre:*` and `post:*` events have not been documented, but as they are used by `@hoodie/client` we decided to make this a breaking change nevertheless
  • Loading branch information
gr2m committed Dec 23, 2016
1 parent 500b4bf commit 72f79c2
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 84 deletions.
7 changes: 5 additions & 2 deletions admin/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = AccountAdmin

var EventEmitter = require('events').EventEmitter
var Hook = require('before-after-hook')

var getUsername = require('../lib/username')
var signIn = require('../lib/sign-in')
Expand Down Expand Up @@ -38,7 +39,8 @@ function AccountAdmin (options) {
emitter: emitter,
account: store.get(),
store: store,
url: options.url
url: options.url,
hook: new Hook()
}

var admin = {
Expand Down Expand Up @@ -70,7 +72,8 @@ function AccountAdmin (options) {

on: events.on.bind(null, state),
one: events.one.bind(null, state),
off: events.off.bind(null, state)
off: events.off.bind(null, state),
hook: state.hook.api
}

// sessions.add can use accounts.find to lookup user id by username
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function Account (options) {
on: events.on.bind(null, state),
one: events.one.bind(null, state),
off: events.off.bind(null, state),
hook: state.hook.api,
validate: require('./lib/validate').bind(null, state)
}
}
83 changes: 29 additions & 54 deletions lib/sign-in.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module.exports = signIn
var Promise = require('lie')
var clone = require('lodash/clone')
var get = require('lodash/get')
var invokeMap = require('lodash/invokeMap')

var internals = module.exports.internals = {}
internals.deserialise = require('../utils/deserialise')
Expand All @@ -15,74 +14,50 @@ function signIn (state, options) {
return Promise.reject(new Error('options.username and options.password is required'))
}

var preHooks = []
// note: the `pre:signin` & `post:signin` events are not considered public
// APIs and might change in future without notice
// https://github.com/hoodiehq/hoodie-account-client/issues/65
state.emitter.emit('pre:signin', { hooks: preHooks })

return Promise.resolve()

.then(function () {
return Promise.all(invokeMap(preHooks, 'call'))
})

.then(function () {
return state.hook('signin', options, function (options) {
return internals.request({
url: state.url + '/session',
method: 'PUT',
body: internals.serialise('session', options)
})
})

.then(function (response) {
var data = internals.deserialise(response.body, {
include: 'account'
})
.then(function (response) {
var data = internals.deserialise(response.body, {
include: 'account'
})

// admins don’t have an account
if (!data.account) {
data.account = {
username: options.username
// admins don’t have an account
if (!data.account) {
data.account = {
username: options.username
}
}
}

// If the username hasn’t changed, emit 'reauthenticate' instead of 'signin'
var emitEvent = 'signin'
if (get(state, 'account.username') === options.username) {
emitEvent = 'reauthenticate'
}

state.account = {
username: data.account.username,
session: {
id: data.id
// If the username hasn’t changed, emit 'reauthenticate' instead of 'signin'
var emitEvent = 'signin'
if (get(state, 'account.username') === options.username) {
emitEvent = 'reauthenticate'
}
}

if (data.account.id) {
state.account.id = data.account.id
}

state.store.set(state.account)

state.emitter.emit(emitEvent, clone(state.account))

return data.account
})
state.account = {
username: data.account.username,
session: {
id: data.id
}
}

.then(function (account) {
var postHooks = []
if (data.account.id) {
state.account.id = data.account.id
}

// note: the `pre:signin` & `post:signin` events are not considered public
// APIs and might change in future without notice
// https://github.com/hoodiehq/hoodie-account-client/issues/65
state.emitter.emit('post:signin', { hooks: postHooks })
internals.saveAccount({
cacheKey: state.cacheKey,
account: state.account
})

return Promise.all(invokeMap(postHooks, 'call'))
state.emitter.emit(emitEvent, clone(state.account))

.then(function () {
return clone(account)
return data.account
})
})
}
33 changes: 6 additions & 27 deletions lib/sign-out.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module.exports = signOut

var clone = require('lodash/clone')
var invokeMap = require('lodash/invokeMap')

var internals = module.exports.internals = {}
internals.request = require('../utils/request')
Expand All @@ -15,19 +14,7 @@ function signOut (state) {

var accountProperties = internals.get(state)

var preHooks = []
// note: the `pre:signout` & `post:signout` events are not considered public
// APIs and might change in future without notice
// https://github.com/hoodiehq/hoodie-account-client/issues/65
state.emitter.emit('pre:signout', { hooks: preHooks })

return Promise.resolve()

.then(function () {
return Promise.all(invokeMap(preHooks, 'call'))
})

.then(function () {
return state.hook('signout', function () {
return internals.request({
method: 'DELETE',
url: state.url + '/session',
Expand All @@ -40,23 +27,15 @@ function signOut (state) {
.then(function () {
state.store.unset()

var accountClone = clone(state.account)
internals.clearSession({
cacheKey: state.cacheKey
})

var accountClone = clone(state.account)
delete state.account

state.emitter.emit('signout', accountClone)

var postHooks = []

// note: the `pre:signout` & `post:signout` events are not considered public
// APIs and might change in future without notice
// https://github.com/hoodiehq/hoodie-account-client/issues/65
state.emitter.emit('post:signout', { hooks: postHooks })

return Promise.all(invokeMap(postHooks, 'call'))

.then(function () {
return clone(accountProperties)
})
return clone(accountProperties)
})
}
4 changes: 3 additions & 1 deletion utils/get-state.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = getState

var Hook = require('before-after-hook')
var EventEmitter = require('events').EventEmitter
var get = require('lodash/get')

Expand All @@ -24,9 +25,10 @@ function getState (options) {
var storedAccount = store.get()

var state = {
account: storedAccount,
cacheKey: cacheKey,
emitter: options.emitter || new EventEmitter(),
account: storedAccount,
hook: new Hook(),
url: options.url,
validate: options.validate || function () {},
store: store
Expand Down

0 comments on commit 72f79c2

Please sign in to comment.