Add error handling messages, clear server errors on validation.
Add missing messages for error conditions that our server can return.
Clear our server error messages when client-side validation occurs, so you
aren't confusingly left with errors after you change the input that caused them.
Ideally, this behaviour would be limited to just the errors that were caused by
the updated field, but clearing all of them seems to be the more user-friendly
behaviour than just leaving them. Baby steps.
Fix a bug in our handling of error messages--ampersand-sync is kind of
inconsistent, and parses our successful responses as JSON, but neglects to parse
the error responses as JSON. So we need to manually parse our errors from JSON
before we can work with them.
We also added a handler for invalid_client error messages, which don't match our
error objects (thanks OAuth2 spec!), so we translate it to one of our error
objects and then add it to the server errors to be displayed.
1 import Model from 'ampersand-model'
2 import Sync from 'ampersand-sync'
4 import config from '../config'
5 import isObject from 'lodash.isobject'
6 import jwtDecode from 'jwt-decode'
8 export default Model.extend({
9 url: config.urlBase + '/token',
12 'Content-Type': 'application/x-www-form-urlencoded',
13 'Authorization': 'Basic ' + btoa(config.clientID + ':' + config.clientSecret),
18 access_token: 'string',
19 refresh_token: 'string',
21 token_created: 'date',
28 return !!this.access_token
31 let d = this.token_created
32 return !!this.refresh_token && (new Date() >= d.setSeconds(d.getSeconds() + this.expires_in - 900))
37 return app.profiles.get(this.profileID)
42 login (email, password) {
47 'grant_type': 'password',
51 options.success = function(resp) {
52 if (!resp.access_token) {
55 let serverAttrs = moc.parse(resp, options)
56 serverAttrs.token_created = new Date()
57 console.log(serverAttrs)
58 if (options.wait) serverAttrs = assign({}, serverAttrs)
59 if (isObject(serverAttrs) && !moc.set(serverAttrs, options)) {
62 const token = jwtDecode(moc.access_token)
63 moc.profileID = token.sub
64 moc.trigger('sync', moc, resp, options)
66 options.error = function(resp) {
67 moc.trigger('error', moc, resp, options)
69 let sync = Sync('create', moc, options)
73 // TODO: write this to chrome.storage.local
77 // TODO: clear all cached data