ducky/web
2015-07-07
Parent:13d27b50d79e
ducky/web/src/models/me.js
Implement subscriptions. Create a Subscription model and a Subscriptions collection, and attach them to the app context. Add a helper to our Profile model to retrieve the Subscription of that model. Still not sure this should be on the Profile--wouldn't it be better on the Me model? Isn't that generally where we would need it?
| 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@14 | 7 import debounce from 'lodash.debounce' |
| paddy@0 | 8 |
| paddy@0 | 9 export default Model.extend({ |
| paddy@20 | 10 url: config.urlBase + '/auth/token', |
| paddy@0 | 11 ajaxConfig: { |
| paddy@0 | 12 headers: { |
| paddy@0 | 13 'Content-Type': 'application/x-www-form-urlencoded', |
| paddy@0 | 14 'Authorization': 'Basic ' + btoa(config.clientID + ':' + config.clientSecret), |
| paddy@0 | 15 } |
| paddy@0 | 16 }, |
| paddy@0 | 17 |
| paddy@0 | 18 props: { |
| paddy@0 | 19 access_token: 'string', |
| paddy@0 | 20 refresh_token: 'string', |
| paddy@0 | 21 expires_in: 'int', |
| paddy@0 | 22 token_created: 'date', |
| paddy@2 | 23 profileID: 'string', |
| paddy@20 | 24 email: 'string', |
| paddy@0 | 25 }, |
| paddy@0 | 26 |
| paddy@14 | 27 profile() { |
| paddy@14 | 28 return new Promise((resolve, reject) => { |
| paddy@14 | 29 app.profiles.getOrFetch(this.profileID, (err, model) => { |
| paddy@14 | 30 if (err) { |
| paddy@14 | 31 reject(err) |
| paddy@14 | 32 } else { |
| paddy@14 | 33 resolve(model) |
| paddy@14 | 34 } |
| paddy@14 | 35 }) |
| paddy@14 | 36 }) |
| paddy@14 | 37 }, |
| paddy@14 | 38 |
| paddy@0 | 39 derived: { |
| paddy@0 | 40 loggedIn () { |
| paddy@0 | 41 return !!this.access_token |
| paddy@0 | 42 }, |
| paddy@14 | 43 tokenExpires () { |
| paddy@14 | 44 let d = this.token_created |
| paddy@14 | 45 d.setSeconds(d.getSeconds() + this.expires_in) |
| paddy@14 | 46 return d |
| paddy@14 | 47 }, |
| paddy@0 | 48 needsRefresh () { |
| paddy@14 | 49 return !!this.refresh_token && (new Date() >= this.tokenExpires) |
| paddy@0 | 50 }, |
| paddy@14 | 51 }, |
| paddy@14 | 52 |
| paddy@14 | 53 initialize() { |
| paddy@14 | 54 this.debouncedWriteToCache = debounce(this.writeToCache, 250) |
| paddy@0 | 55 }, |
| paddy@0 | 56 |
| paddy@0 | 57 login (email, password) { |
| paddy@0 | 58 let options = { |
| paddy@0 | 59 data: qs.stringify({ |
| paddy@0 | 60 'username': email, |
| paddy@0 | 61 'password': password, |
| paddy@0 | 62 'grant_type': 'password', |
| paddy@20 | 63 'scope': 'subscriptions', |
| paddy@0 | 64 }), |
| paddy@0 | 65 } |
| paddy@0 | 66 let moc = this |
| paddy@0 | 67 options.success = function(resp) { |
| paddy@0 | 68 if (!resp.access_token) { |
| paddy@0 | 69 return false |
| paddy@0 | 70 } |
| paddy@0 | 71 let serverAttrs = moc.parse(resp, options) |
| paddy@0 | 72 serverAttrs.token_created = new Date() |
| paddy@0 | 73 if (options.wait) serverAttrs = assign({}, serverAttrs) |
| paddy@0 | 74 if (isObject(serverAttrs) && !moc.set(serverAttrs, options)) { |
| paddy@0 | 75 return false |
| paddy@0 | 76 } |
| paddy@2 | 77 const token = jwtDecode(moc.access_token) |
| paddy@2 | 78 moc.profileID = token.sub |
| paddy@20 | 79 moc.email = email |
| paddy@0 | 80 moc.trigger('sync', moc, resp, options) |
| paddy@0 | 81 } |
| paddy@0 | 82 options.error = function(resp) { |
| paddy@0 | 83 moc.trigger('error', moc, resp, options) |
| paddy@0 | 84 } |
| paddy@0 | 85 let sync = Sync('create', moc, options) |
| paddy@0 | 86 }, |
| paddy@0 | 87 |
| paddy@0 | 88 writeToCache () { |
| paddy@14 | 89 const data = JSON.stringify(this) |
| paddy@20 | 90 localStorage.setItem('me', data) |
| paddy@14 | 91 }, |
| paddy@14 | 92 |
| paddy@14 | 93 load () { |
| paddy@14 | 94 let moc = this |
| paddy@20 | 95 const resp = localStorage.getItem('me') |
| paddy@20 | 96 if (resp) { |
| paddy@20 | 97 const loaded = this.parse(JSON.parse(resp)) |
| paddy@20 | 98 moc.set(loaded, {silent: true}) |
| paddy@20 | 99 } |
| paddy@14 | 100 return this |
| paddy@0 | 101 }, |
| paddy@0 | 102 |
| paddy@0 | 103 logout () { |
| paddy@20 | 104 localStorage.removeItem('me') |
| paddy@0 | 105 }, |
| paddy@0 | 106 |
| paddy@0 | 107 }) |