chore: port auth addon from demo branch

This commit is contained in:
Randall Morey committed 2020-07-24 11:15:40 -04:00
1 parent 26388b8527
commit 4ef58a0d6d
14 files changed
+558 -5

No files matched your search

@@ -0,0 +1,6 @@
import PasswordAuthenticator from 'auth/authenticators/password';
export default class ApplicationPasswordAuthenticator extends PasswordAuthenticator {
authEndpoint = '/authenticate';
deauthEndpoint = '/deauthenticate';
}
@@ -0,0 +1,6 @@
import CookieSessionStore from 'auth/session-stores/cookie';
export default class ApplicationCookieSessionStore extends CookieSessionStore {
cookiePath = '/';
cookieName = 'my-cookie';
}
@@ -0,0 +1,3 @@
import LocalStorageSessionStore from 'auth/session-stores/local-storage';
export default class ApplicationLocalStorageSessionStore extends LocalStorageSessionStore {}
+22
View File
@@ -0,0 +1,22 @@
export default function () {
// These comments are here to help you get started. Feel free to delete them.
/*
Config (with defaults).
Note: these only affect routes defined *after* them!
*/
// this.urlPrefix = ''; // make this `http://localhost:8080`, for example, if your API is on a different server
// this.namespace = ''; // make this `/api`, for example, if your API is namespaced
// this.timing = 400; // delay for each request, automatically set to 0 during testing
/*
Shorthand cheatsheet:
this.get('/posts');
this.post('/posts');
this.get('/posts/:id');
this.put('/posts/:id'); // or this.patch
this.del('/posts/:id');
https://www.ember-cli-mirage.com/docs/route-handlers/shorthands
*/
}
@@ -0,0 +1,7 @@
export default function (/* server */) {
/*
Seed your development database using your factories.
This data will not be loaded in your tests.
*/
// server.createList('post', 10);
}
@@ -0,0 +1,3 @@
import { JSONAPISerializer } from 'ember-cli-mirage';
export default JSONAPISerializer.extend({});
@@ -0,0 +1,92 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { Response } from 'miragejs';
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
module('Unit | Authenticator | password', function (hooks) {
setupTest(hooks);
setupMirage(hooks);
test('it authenticates to the specified authEndpoint', async function (assert) {
assert.expect(2);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.authEndpoint, (schema, request) => {
const json = JSON.parse(request.requestBody);
assert.ok(json.token_type, 'Requested token cookies by default');
return new Response(200);
});
await authenticator.authenticate({}, '').then(() => {
assert.ok(true, 'authentication succeeded');
});
});
test('it can authenticate without requesting cookies', async function (assert) {
assert.expect(2);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.authEndpoint, (schema, request) => {
const json = JSON.parse(request.requestBody);
assert.notOk(json.token_type, 'Did not request tokens cookies');
return new Response(200);
});
await authenticator.authenticate({}, '', false).then(() => {
assert.ok(true, 'authentication succeeded');
});
});
test('it authenticates with the expected payload', async function (assert) {
assert.expect(1);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.authEndpoint, (schema, request) => {
const json = JSON.parse(request.requestBody);
assert.deepEqual(json, {
auth_method_id: '123',
token_type: 'cookie',
credentials: {
name: 'foo',
password: 'bar',
},
});
return new Response(200);
});
const creds = {
identification: 'foo',
password: 'bar',
};
const authMethodID = '123';
await authenticator.authenticate(creds, authMethodID);
});
test('it rejects if the endpoint sends an error status code', async function (assert) {
assert.expect(1);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.authEndpoint, () => {
return new Response(400);
});
await authenticator.authenticate({}).catch(() => {
assert.ok(true, 'authentication failed');
});
});
test('it deauthenticates on invalidation', async function (assert) {
assert.expect(1);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.deauthEndpoint, () => {
assert.ok(true, 'deauthentication occurred');
return new Response(200);
});
await authenticator.invalidate();
});
test('it invalidation succeeds even if the deauthentication request fails', async function (assert) {
assert.expect(2);
const authenticator = this.owner.lookup('authenticator:password');
this.server.post(authenticator.deauthEndpoint, () => {
assert.ok(true, 'deauthentication was requested');
return new Response(500);
});
await authenticator
.invalidate()
.then(() => assert.ok(true))
.catch(() => assert.notOk(true, 'uh oh, this should not happen'));
});
});
@@ -0,0 +1,92 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Session Store | cookie', function (hooks) {
setupTest(hooks);
let sessionStore;
hooks.beforeEach(function () {
sessionStore = this.owner.lookup('session-store:cookie');
sessionStore.clear();
});
hooks.afterEach(function () {
sessionStore.clear();
});
test('it restores a session if both necessary cookies are present (session exists)', async function (assert) {
assert.expect(2);
sessionStore.cookies.write(sessionStore.cookieName, 'token-value', {
path: '/',
});
sessionStore.cookies.write(
sessionStore.authenticatorCookieName,
'authenticator-name',
{ path: '/' }
);
assert.ok(sessionStore.sessionExists);
const session = await sessionStore.restore();
assert.deepEqual(session, {
authenticated: {
authenticator: 'authenticator-name',
},
});
});
test('it rejects restore if the session does not exist', async function (assert) {
assert.expect(2);
assert.notOk(sessionStore.sessionExists);
await sessionStore.restore().catch(() => {});
assert.ok(true, 'Rejected');
});
test('it cleans up cookies on restore rejection', async function (assert) {
assert.expect(4);
// For session cookie
sessionStore.cookies.write(sessionStore.cookieName, 'token-value', {
path: '/',
});
assert.ok(
sessionStore.cookies.exists(sessionStore.cookieName),
'cookie exists'
);
await sessionStore.restore().catch(() => {});
assert.notOk(
sessionStore.cookies.exists(sessionStore.cookieName),
'cookie was cleared'
);
// For authenticator name cookie
sessionStore.cookies.write(
sessionStore.authenticatorCookieName,
'authenticator-name',
{ path: '/' }
);
assert.ok(
sessionStore.cookies.exists(sessionStore.authenticatorCookieName),
'cookie exists'
);
await sessionStore.restore().catch(() => {});
assert.notOk(
sessionStore.cookies.exists(sessionStore.authenticatorCookieName),
'cookie was cleared'
);
});
test('it persists only an authenticator name cookie, since the server persists the session cookie', async function (assert) {
assert.expect(4);
assert.notOk(sessionStore.cookies.exists(sessionStore.cookieName));
assert.notOk(
sessionStore.cookies.exists(sessionStore.authenticatorCookieName)
);
sessionStore.persist({ authenticated: { authenticator: 'foobar' } });
assert.notOk(
sessionStore.cookies.exists(sessionStore.cookieName),
'session cookie was not set'
);
assert.equal(
sessionStore.cookies.read(sessionStore.authenticatorCookieName),
'foobar'
);
});
});