ducky/web
ducky/web/src/models/me.js
Stop ignoring our build folder. Now that our HTML lives in our build folder, we should probably stop ignoring it. This means that an `hg clone` followed by an `npm install` followed by an `npm run deploy` will work. I hope.
| 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 }) |