ducky/web

Paddy 2015-07-07 Parent:13d27b50d79e

21:bc1478742a50 Go to Latest

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?

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@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 })