ducky/web

Paddy 2015-05-31 Parent:b9d0efb44eaa Child:275a83e4c02e

6:a641906b8267 Go to Latest

ducky/web/src/models/me.js

Enable catch-all in our ValidationError component. We're doing this an ugly, hacky way. But it works, and right now, that's what counts. To match our params/fields/headers properties on the ValidationError component, we're going to add the notParams/notFields/notHeaders properties--they match any error _not_ targeting those params/fields/headers. Basically, "any error that wouldn't be caught by these filters". Which is an ugly, but workable, solution for a catch-all ValidationError--just tell it to catch anything but the params/fields/headers that are being handled by the other ValidationErrors. Our implementation of this in the RegisterPage component validates (ha!) that it's at least workable model, if not overly pretty. Also, I anticipate some human error bugs in the future, where one of the field-specific ValidationErrors gets updated and the catch-all ValidationError does not. But whatever. For now, this is Good Enoughâ„¢.

History
paddy@0 1 import Model from 'ampersand-model'
paddy@0 2 import Sync from 'ampersand-sync'
paddy@0 3 import qs from 'qs'
paddy@0 4 import config from '../config'
paddy@0 5 import isObject from 'lodash.isobject'
paddy@2 6 import jwtDecode from 'jwt-decode'
paddy@0 7
paddy@0 8 export default Model.extend({
paddy@0 9 url: config.urlBase + '/token',
paddy@0 10 ajaxConfig: {
paddy@0 11 headers: {
paddy@0 12 'Content-Type': 'application/x-www-form-urlencoded',
paddy@0 13 'Authorization': 'Basic ' + btoa(config.clientID + ':' + config.clientSecret),
paddy@0 14 }
paddy@0 15 },
paddy@0 16
paddy@0 17 props: {
paddy@0 18 access_token: 'string',
paddy@0 19 refresh_token: 'string',
paddy@0 20 expires_in: 'int',
paddy@0 21 token_created: 'date',
paddy@0 22 name: 'string',
paddy@2 23 profileID: 'string',
paddy@0 24 },
paddy@0 25
paddy@0 26 derived: {
paddy@0 27 loggedIn () {
paddy@0 28 return !!this.access_token
paddy@0 29 },
paddy@0 30 needsRefresh () {
paddy@0 31 let d = this.token_created
paddy@0 32 return !!this.refresh_token && (new Date() >= d.setSeconds(d.getSeconds() + this.expires_in - 900))
paddy@0 33 },
paddy@2 34 profile: {
paddy@2 35 deps: ['profileID'],
paddy@2 36 fn () {
paddy@2 37 return app.profiles.get(this.profileID)
paddy@2 38 },
paddy@2 39 },
paddy@0 40 },
paddy@0 41
paddy@0 42 login (email, password) {
paddy@0 43 let options = {
paddy@0 44 data: qs.stringify({
paddy@0 45 'username': email,
paddy@0 46 'password': password,
paddy@0 47 'grant_type': 'password',
paddy@0 48 }),
paddy@0 49 }
paddy@0 50 let moc = this
paddy@0 51 options.success = function(resp) {
paddy@0 52 if (!resp.access_token) {
paddy@0 53 return false
paddy@0 54 }
paddy@0 55 let serverAttrs = moc.parse(resp, options)
paddy@0 56 serverAttrs.token_created = new Date()
paddy@0 57 console.log(serverAttrs)
paddy@0 58 if (options.wait) serverAttrs = assign({}, serverAttrs)
paddy@0 59 if (isObject(serverAttrs) && !moc.set(serverAttrs, options)) {
paddy@0 60 return false
paddy@0 61 }
paddy@2 62 const token = jwtDecode(moc.access_token)
paddy@2 63 moc.profileID = token.sub
paddy@0 64 moc.trigger('sync', moc, resp, options)
paddy@0 65 }
paddy@0 66 options.error = function(resp) {
paddy@0 67 moc.trigger('error', moc, resp, options)
paddy@0 68 }
paddy@0 69 let sync = Sync('create', moc, options)
paddy@0 70 },
paddy@0 71
paddy@0 72 writeToCache () {
paddy@0 73 // TODO: write this to chrome.storage.local
paddy@0 74 },
paddy@0 75
paddy@0 76 logout () {
paddy@0 77 // TODO: clear all cached data
paddy@0 78 },
paddy@0 79
paddy@0 80 })