Skip to content

Commit

Permalink
Merge branch 'master' into fastboot
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenwu committed Nov 14, 2016
1 parent 0b3a729 commit 4e5c6d1
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 55 deletions.
25 changes: 22 additions & 3 deletions addon/session-stores/adaptive.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ const { computed } = Ember;

const LOCAL_STORAGE_TEST_KEY = '_ember_simple_auth_test_key';

const proxyToInternalStore = function() {
return computed({
get(key) {
return this.get(`_${key}`);
},
set(key, value) {
this.set(`_${key}`, value);
let _store = this.get('_store');
if (_store) {
_store.set(key, value);
}
return value;
}
});
};

/**
Session store that persists data in the browser's `localStorage` (see
{{#crossLink "LocalStorageStore"}}{{/crossLink}}) if that is available or in
Expand Down Expand Up @@ -58,7 +74,8 @@ export default Base.extend({
@default null
@public
*/
cookieDomain: null,
_cookieDomain: null,
cookieDomain: proxyToInternalStore(),

/**
The name of the cookie to use if `localStorage` is not available.
Expand All @@ -68,7 +85,8 @@ export default Base.extend({
@default ember_simple_auth-session
@public
*/
cookieName: 'ember_simple_auth-session',
_cookieName: 'ember_simple_auth-session',
cookieName: proxyToInternalStore(),

/**
The expiration time for the cookie in seconds if `localStorage` is not
Expand All @@ -80,7 +98,8 @@ export default Base.extend({
@type Integer
@public
*/
cookieExpirationTime: null,
_cookieExpirationTime: null,
cookieExpirationTime: proxyToInternalStore(),

_isLocalStorageAvailable: computed(function() {
try {
Expand Down
58 changes: 46 additions & 12 deletions addon/session-stores/cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,21 @@ import BaseStore from './base';
import objectsAreEqual from '../utils/objects-are-equal';
import getOwner from 'ember-getowner-polyfill';

const { RSVP, computed, inject: { service }, run: { next, cancel, later }, isEmpty, typeOf, testing } = Ember;
const { RSVP, computed, inject: { service }, run: { next, cancel, later, scheduleOnce }, isEmpty, typeOf, testing, isPresent, K, A, assign } = Ember;

const persistingProperty = function(beforeSet = K) {
return computed({
get(key) {
return this.get(`_${key}`);
},
set(key, value) {
beforeSet.apply(this);
this.set(`_${key}`, value);
scheduleOnce('actions', this, this.rewriteCookie);
return value;
}
});
};

/**
Session store that persists data in a cookie.
Expand Down Expand Up @@ -55,7 +69,8 @@ export default BaseStore.extend({
@default null
@public
*/
cookieDomain: null,
_cookieDomain: null,
cookieDomain: persistingProperty(),

/**
The name of the cookie.
Expand All @@ -65,7 +80,10 @@ export default BaseStore.extend({
@default ember_simple_auth-session
@public
*/
cookieName: 'ember_simple_auth-session',
_cookieName: 'ember_simple_auth-session',
cookieName: persistingProperty(function() {
this._oldCookieName = this._cookieName;
}),

/**
The expiration time for the cookie in seconds. A value of `null` will make
Expand All @@ -77,7 +95,8 @@ export default BaseStore.extend({
@type Integer
@public
*/
cookieExpirationTime: null,
_cookieExpirationTime: null,
cookieExpirationTime: persistingProperty(),

_cookies: service('cookies'),

Expand Down Expand Up @@ -146,7 +165,7 @@ export default BaseStore.extend({
@public
*/
restore() {
let data = this._read(this.cookieName);
let data = this._read(this.get('cookieName'));
if (isEmpty(data)) {
return RSVP.resolve({});
} else {
Expand All @@ -162,7 +181,7 @@ export default BaseStore.extend({
@public
*/
clear() {
this._write(null, 0);
this._write('', 0);
this._lastData = {};
return RSVP.resolve();
},
Expand All @@ -172,23 +191,30 @@ export default BaseStore.extend({
},

_calculateExpirationTime() {
let cachedExpirationTime = this._read(`${this.cookieName}-expiration_time`);
let cachedExpirationTime = this._read(`${this.get('cookieName')}-expiration_time`);
cachedExpirationTime = !!cachedExpirationTime ? new Date().getTime() + cachedExpirationTime * 1000 : null;
return !!this.cookieExpirationTime ? new Date().getTime() + this.cookieExpirationTime * 1000 : cachedExpirationTime;
return this.get('cookieExpirationTime') ? new Date().getTime() + this.get('cookieExpirationTime') * 1000 : cachedExpirationTime;
},

_write(value, expiration) {
let cookieOptions = {
domain: this.cookieDomain,
domain: this.get('cookieDomain'),
expires: isEmpty(expiration) ? null : new Date(expiration),
path: '/',
secure: this.get('_secureCookies')
};
this.get('_cookies').write(this.cookieName, value, cookieOptions);
if (this._oldCookieName) {
A([this._oldCookieName, `${this._oldCookieName}-expiration_time`]).forEach((oldCookie) => {
let expires = new Date(0);
this.get('_cookies').write(oldCookie, null, assign({}, cookieOptions, { expires }));
});
delete this._oldCookieName;
}
this.get('_cookies').write(this.get('cookieName'), value, cookieOptions);
if (!isEmpty(expiration)) {
let expirationCookieName = `${this.cookieName}-expiration_time`;
let expirationCookieName = `${this.get('cookieName')}-expiration_time`;
let cachedExpirationTime = this.get('_cookies').read(expirationCookieName);
this.get('_cookies').write(expirationCookieName, this.cookieExpirationTime || cachedExpirationTime, cookieOptions);
this.get('_cookies').write(expirationCookieName, this.get('cookieExpirationTime') || cachedExpirationTime, cookieOptions);
}
},

Expand Down Expand Up @@ -225,5 +251,13 @@ export default BaseStore.extend({
} else {
return RSVP.resolve();
}
},

rewriteCookie() {
const data = this._read(this._oldCookieName);
if (isPresent(data)) {
const expiration = this._calculateExpirationTime();
this._write(data, expiration);
}
}
});
1 change: 1 addition & 0 deletions app/routes/application.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Ember from 'ember';

// Ensure the application route exists for ember-simple-auth's `setup-session-restoration` initializer
export default Ember.Route.extend();
12 changes: 6 additions & 6 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "ember-simple-auth",
"dependencies": {
"base64": "~1.0.0",
"bootstrap": "~3.3.7",
"ember": "~2.7.0",
"mocha": "~2.2.4",
"chai": "~2.3.0",
"ember-mocha-adapter": "~0.3.1",
"ember": "~2.7.0",
"ember-cli-shims": "0.1.1",
"sinonjs": "~1.17.1",
"base64": "~1.0.0",
"pretender": "~1.1.0"
"ember-mocha-adapter": "~0.3.1",
"mocha": "~2.2.4",
"pretender": "~1.1.0",
"sinonjs": "~1.17.1"
}
}
9 changes: 6 additions & 3 deletions guides/managing-current-user.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ import Ember from 'ember';
const { inject: { service }, isEmpty, RSVP } = Ember;

export default Ember.Service.extend({
session: service('session'),
store: service(),

load() {
return this.get('store').find('user', 'me').then((user) => {
this.set('user', user);
});
if (this.get('session.isAuthenticated')) {
return this.get('store').find('user', 'me').then((user) => {
this.set('user', user);
});
}
}
});
```
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@
],
"dependencies": {
"ember-cli-babel": "^5.1.6",
"ember-cli-import-polyfill": "^0.2.0",
"ember-cli-is-package-missing": "^1.0.0",
"ember-cookies": "0.0.9",
"ember-getowner-polyfill": "1.0.1",
"silent-error": "^1.0.0",
"ember-network": "^0.3.0",
"ember-cli-import-polyfill": "^0.2.0"
"silent-error": "^1.0.0"
},
"ember-addon": {
"configPath": "tests/dummy/config"
Expand Down
56 changes: 36 additions & 20 deletions tests/unit/session-stores/adaptive-test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Ember from 'ember';
import { describe, beforeEach, afterEach } from 'mocha';
import { it } from 'ember-mocha';
import { expect } from 'chai';
import sinon from 'sinon';
import Adaptive from 'ember-simple-auth/session-stores/adaptive';
import itBehavesLikeAStore from './shared/store-behavior';
import itBehavesLikeACookieStore from './shared/cookie-store-behavior';
import FakeCookieService from '../../helpers/fake-cookie-service';

const { assign: emberAssign, merge } = Ember;
const { assign: emberAssign, merge, run } = Ember;
const assign = emberAssign || merge;

describe('AdaptiveStore', () => {
Expand Down Expand Up @@ -34,10 +36,18 @@ describe('AdaptiveStore', () => {
});

describe('when localStorage is not available', () => {
let cookieService;
beforeEach(() => {
store = Adaptive.create({ _isLocalStorageAvailable: false });
store.set('_store._cookies', FakeCookieService.create());
store.set('_store._fastboot', { isFastBoot: false });
cookieService = FakeCookieService.create();
sinon.spy(cookieService, 'read');
sinon.spy(cookieService, 'write');
store = Adaptive.extend({
_createStore(storeType, options) {
return this._super(storeType, assign({}, options, { _isFastBoot: false, _cookies: cookieService }));
}
}).create({
_isLocalStorageAvailable: false
});
});

itBehavesLikeAStore({
Expand All @@ -46,20 +56,26 @@ describe('AdaptiveStore', () => {
}
});

itBehavesLikeACookieStore({
createStore(cookiesService, options = {}) {
options._isLocalStorageAvailable = false;
const store = Adaptive.create(options);
store.set('_store._cookies', cookiesService);
store.set('_store._fastboot', { isFastBoot: false });
return store;
},
renew(store, data) {
store.get('_store')._renew(data);
},
sync(store) {
store.get('_store')._syncData();
}
it('persists to cookie when cookie attributes change', () => {
let now = new Date();

run(() => {
store.persist({ key: 'value' });
store.setProperties({
cookieName: 'test:session',
cookieExpirationTime: 60
});
});

expect(cookieService.write).to.have.been.calledWith(
'test:session-expiration_time',
60,
sinon.match(function({ domain, expires, path, secure }) {
return domain === null &&
path === '/' &&
secure === false && expires >= new Date(now.getTime() + 60 * 1000);
})
);
});
});
});
});
5 changes: 5 additions & 0 deletions tests/unit/session-stores/cookie-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* jshint expr:true */
import { describe, beforeEach, afterEach } from 'mocha';
import sinon from 'sinon';
import Cookie from 'ember-simple-auth/session-stores/cookie';
import itBehavesLikeAStore from './shared/store-behavior';
import itBehavesLikeACookieStore from './shared/cookie-store-behavior';
Expand Down Expand Up @@ -40,6 +41,10 @@ describe('CookieStore', () => {
},
sync(store) {
store._syncData();
},
spyRewriteCookieMethod(store) {
sinon.spy(store, 'rewriteCookie');
return store.rewriteCookie;
}
});
});
Loading

0 comments on commit 4e5c6d1

Please sign in to comment.