Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge branch 'master' into fastboot #1098

Merged
merged 6 commits into from
Nov 21, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
57 changes: 45 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 } = 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,29 @@ 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) => {
this.get('_cookies').clear(oldCookie);
});
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 +250,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
5 changes: 5 additions & 0 deletions tests/helpers/fake-cookie-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,10 @@ export default EmberObject.extend({
} else {
this._content[name] = encodeURIComponent(value);
}
},

clear(name) {
let expires = new Date(0);
this.write(name, null, { expires });
}
});
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