Skip to content

Commit

Permalink
[SDK-1813] Send connection scope config to enterprise connections (au…
Browse files Browse the repository at this point in the history
…th0#1910)

* Send connectionScope through to enterprise connections

* Update readme
  • Loading branch information
Steve Hobbs authored Aug 7, 2020
1 parent 6296818 commit 80ec976
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ var options = {
- **responseMode {String}**: Should be set to `"form_post"` if you want the code or the token to be transmitted via an HTTP POST request to the `redirectUrl` instead of being included in its query or fragment parts. Otherwise, it should be omitted.
- **responseType {String}**: Should be set to `"token"` for Single Page Applications, and `"code"` otherwise. Also, `"id_token"` is supported for the first case. Defaults to `"code"` when `redirectUrl` is provided, and to `"token"` otherwise.
- **sso {Boolean}**: Determines whether Single Sign-On is enabled or not in **Lock**. The Auth0 SSO session will be created regardless of this option if SSO is enabled for your application or tenant.
- **connectionScopes {Object}**: Allows you to set scopes to be sent to the oauth2/social connection for authentication.
- **connectionScopes {Object}**: Allows you to set scopes to be sent to the oauth2/social/enterprise connection for authentication.

#### Database options

Expand Down
101 changes: 101 additions & 0 deletions src/__tests__/connection/enterprise/actions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import I from 'immutable';
import { logIn } from '../../../connection/enterprise/actions';
import * as l from '../../../core/index';
import { setField, getFieldValue } from '../../../field/index';

jest.mock('connection/database/index', () => ({
databaseLogInWithEmail: jest.fn(() => true)
}));

jest.mock('store/index', () => ({
read: jest.fn(() => 'model'),
getEntity: 'getEntity',
swap: jest.fn(),
updateEntity: 'updateEntity'
}));

jest.mock('connection/enterprise', () => ({
matchConnection: jest.fn(),
enterpriseActiveFlowConnection: jest.fn(),
isHRDActive: jest.fn()
}));

jest.mock('core/actions', () => ({
logIn: jest.fn()
}));

describe('Login with connection scopes', () => {
let lock;

beforeEach(() => {
lock = I.fromJS({ id: '__lock__' });
require('store/index').read.mockReturnValue(lock);
});

afterEach(() => {
jest.resetAllMocks();
});

describe('for an SSO connection', () => {
it.only('passes connectionScopes to the connection', () => {
lock = l.setup('__lock__', 'client', 'domain', {
auth: {
connectionScopes: {
'sso-connection': ['offline_access']
}
}
});

lock = setField(lock, 'email', 'test@test.com');

require('store/index').read.mockReturnValue(lock);

require('connection/enterprise').matchConnection.mockReturnValue(
I.fromJS({ name: 'sso-connection' })
);

const coreActions = require('core/actions');

logIn('__lock__');

expect(coreActions.logIn).toHaveBeenCalledWith('__lock__', ['email'], {
connection_scope: ['offline_access'],
connection: 'sso-connection',
login_hint: 'test@test.com'
});
});
});

describe('for a non-SSO connection', () => {
it.only('passes connectionScopes to the connection', () => {
lock = l.setup('__lock__', 'client', 'domain', {
auth: {
connectionScopes: {
'enterprise-connection': ['offline_access']
}
}
});

lock = setField(lock, 'password', 'test');
lock = setField(lock, 'username', 'test');

require('store/index').read.mockReturnValue(lock);

require('connection/enterprise').enterpriseActiveFlowConnection.mockReturnValue(
I.fromJS({ name: 'enterprise-connection' })
);

const coreActions = require('core/actions');

logIn('__lock__');

expect(coreActions.logIn).toHaveBeenCalledWith('__lock__', ['password', 'username'], {
connection_scope: ['offline_access'],
connection: 'enterprise-connection',
username: 'test',
password: 'test',
login_hint: 'test'
});
});
});
});
23 changes: 19 additions & 4 deletions src/connection/enterprise/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,30 @@ export function cancelHRD(id) {
});
}

function getConnectionScopesFrom(m, connection) {
const connectionScopes = l.auth.connectionScopes(m);
return connectionScopes.get(connection.get('name'));
}

export function logIn(id) {
const m = read(getEntity, 'lock', id);
const email = getFieldValue(m, databaseLogInWithEmail(m) ? 'email' : 'username');
const ssoConnection = matchConnection(m, email);
const enterpriseConnection = enterpriseActiveFlowConnection(m);
const connectionScopes = getConnectionScopesFrom(m, ssoConnection || enterpriseConnection);

const params = {
connection_scope: connectionScopes ? connectionScopes.toJS() : undefined
};

if (ssoConnection && !isHRDActive(m)) {
return logInSSO(id, ssoConnection);
return logInSSO(id, ssoConnection, params);
}

logInActiveFlow(id);
logInActiveFlow(id, params);
}

function logInActiveFlow(id) {
function logInActiveFlow(id, params) {
const m = read(getEntity, 'lock', id);
const usernameField = isHRDActive(m) || !databaseLogInWithEmail(m) ? 'username' : 'email';

Expand All @@ -54,22 +65,26 @@ function logInActiveFlow(id) {
: originalUsername;

coreLogIn(id, ['password', usernameField], {
...params,
connection: connection ? connection.get('name') : null,
username: username,
password: getFieldValue(m, 'password'),
login_hint: username
});
}

function logInSSO(id, connection) {
function logInSSO(id, connection, params) {
const m = read(getEntity, 'lock', id);
const field = databaseLogInWithEmail(m) ? 'email' : 'username';

l.emitEvent(m, 'sso login', {
lockID: id,
connection: connection,
field: field
});

coreLogIn(id, [field], {
...params,
connection: connection.get('name'),
login_hint: getFieldValue(m, field)
});
Expand Down

0 comments on commit 80ec976

Please sign in to comment.