ducky/web

Paddy 2015-06-30 Parent:b9d0efb44eaa Child:275a83e4c02e

12:791aec3eb17b Go to Latest

ducky/web/src/models/me.js

Update our profile model to use our refresh helper. Update our profile model to send the correct authorization header when making requests, and if the request fails because the OAuth token has expired, try to use the refresh token to obtain a new access token, then retry the request.

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