Skip to content

Commit

Permalink
adds unit tests for basic auth with password
Browse files Browse the repository at this point in the history
OKTA-382083
<<<Jenkins Check-In of Tested SHA: 0b2579e for eng_productivity_ci_bot_okta@okta.com>>>
Artifact: okta-auth-js
Files changed count: 7
PR Link: "#733"
  • Loading branch information
aarongranick-okta authored and eng-prod-CI-bot-okta committed May 12, 2021
1 parent 6fcce31 commit 60e13da
Show file tree
Hide file tree
Showing 7 changed files with 900 additions and 7 deletions.
10 changes: 5 additions & 5 deletions lib/idx/remediate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/* eslint-disable complexity */
import idx from '@okta/okta-idx-js';
import { AuthSdkError } from '../errors';
import { Base as Remeditor } from './remediators';
import { Base as Remediator } from './remediators';
import { RunOptions } from './run';
import LoopMonitor from './RemediationLoopMonitor';
import {
Expand Down Expand Up @@ -30,12 +30,12 @@ interface RemediationResponse {
}

// Return first match idxRemediation in allowed remediators
export function getRemeditor(
export function getRemediator(
flow: RemediationFlow,
allowedNextSteps: string[],
idxRemediations: IdxRemediation[],
values: RemediationValues,
): Remeditor {
): Remediator {
let remediator;
const remediatorCandidates = [];
for (let remediation of idxRemediations) {
Expand Down Expand Up @@ -101,7 +101,7 @@ export async function remediate(
}
}

const remediator = getRemeditor(flow, allowedNextSteps, neededToProceed, values);
const remediator = getRemediator(flow, allowedNextSteps, neededToProceed, values);

if (!remediator) {
throw new AuthSdkError(
Expand Down Expand Up @@ -141,7 +141,7 @@ export async function remediate(
}

// We may want to trim the values bag for the next remediation
// Let the remeditor decide what the values should be (default to current values)
// Let the remediator decide what the values should be (default to current values)
values = remediator.getValues();
return remediate(idxResponse, values, loopMonitor, options); // recursive call
} catch (e) {
Expand Down
5 changes: 5 additions & 0 deletions lib/idx/transactionMeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ import { OktaAuth, IdxTransactionMeta } from '../types';
import { warn } from '../util';
import { getOAuthUrls } from '../oidc';

// Calculate new values
export async function createTransactionMeta(authClient: OktaAuth) {
return authClient.token.prepareTokenParams();
}

export async function getTransactionMeta (authClient: OktaAuth): Promise<IdxTransactionMeta> {
// Load existing transaction meta from storage
if (authClient.transactionManager.exists()) {
Expand Down
4 changes: 2 additions & 2 deletions lib/idx/types.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { IdxTransactionMeta } from '../types/Transaction';
import { Base as Remeditor } from './remediators';
import { Base as Remediator } from './remediators';

export { RemediationValues } from './remediators';
export { AuthenticationOptions } from './authenticate';
export { RegistrationOptions } from './register';
export { PasswordRecoveryOptions } from './recoverPassword';
export { CancelOptions } from './cancel';

export type RemediationFlow = Record<string, typeof Remeditor>;
export type RemediationFlow = Record<string, typeof Remediator>;

// A map from IDX data values (server spec) to RemediationValues (client spec)
export type IdxToRemediationValueMap = Record<string, string[] | string | boolean>;
Expand Down
133 changes: 133 additions & 0 deletions test/spec/idx/authenticate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { authenticate } from '../../../lib/idx/authenticate';

jest.mock('../../../lib/idx/interact', () => {
return {
interact: () => {}
};
});

const mocked = {
interact: require('../../../lib/idx/interact'),
};

describe('idx/authenticate', () => {
let testContext;
beforeEach(() => {
const successResponse = {
interactionCode: 'idx-interactionCode',
neededToProceed: []
};
const identifyResponse = {
proceed: () => Promise.resolve(successResponse),
neededToProceed: [{
name: 'identify',
value:[{
name: 'identifier',
label: 'Username'
}]
}]
};
const challengePasswordResponse = {
proceed: () => Promise.resolve(successResponse),
neededToProceed: [{
name: 'challenge-authenticator',
value: [{
name: 'credentials'
}],
relatesTo: {
value: {
type: 'password'
}
}
}]
};
const interactResponse = {
idxResponse: identifyResponse,
stateHandle: 'idx-stateHandle'
};

jest.spyOn(mocked.interact, 'interact').mockImplementation(() => testContext.interactResponse);

const transactionMeta = {
state: 'meta-state',
codeVerifier: 'meta-code',
clientId: 'meta-clientId',
redirectUri: 'meta-redirectUri',
scopes: ['meta'],
urls: { authorizeUrl: 'meta-authorizeUrl' },
ignoreSignature: true
};
const tokenResponse = {
tokens: {
fakeToken: true
}
};
const authClient = {
transactionManager: {
load: () => transactionMeta,
clear: () => {}
},
token: {
exchangeCodeForTokens: () => Promise.resolve(tokenResponse)
}
};
jest.spyOn(authClient.token, 'exchangeCodeForTokens');

testContext = {
interactResponse,
successResponse,
identifyResponse,
challengePasswordResponse,
tokenResponse,
transactionMeta,
authClient
};
});

it('returns an auth transaction', async () => {
const { authClient, tokenResponse } = testContext;
const res = await authenticate(authClient, { username: 'fake' });
expect(res).toEqual({
'data': {
'status': 0,
'tokens': tokenResponse.tokens,
},
'status': 0,
'tokens': tokenResponse.tokens,
});
});

describe('basic authentication', () => {
beforeEach(() => {
const { identifyResponse, challengePasswordResponse } = testContext;
identifyResponse.proceed = () => Promise.resolve(challengePasswordResponse);
jest.spyOn(identifyResponse, 'proceed');
jest.spyOn(challengePasswordResponse, 'proceed');
});

it('can authenticate, passing username and password', async () => {
const { authClient, identifyResponse, challengePasswordResponse, tokenResponse } = testContext;
const res = await authenticate(authClient, { username: 'fakeuser', password: 'fakepass' });
expect(res).toEqual({
'data': {
'status': 0,
'tokens': tokenResponse.tokens,
},
'status': 0,
'tokens': tokenResponse.tokens,
});
expect(identifyResponse.proceed).toHaveBeenCalledWith('identify', { identifier: 'fakeuser' });
expect(challengePasswordResponse.proceed).toHaveBeenCalledWith('challenge-authenticator', { credentials: { passcode: 'fakepass' }});
expect(authClient.token.exchangeCodeForTokens).toHaveBeenCalledWith({
clientId: 'meta-clientId',
codeVerifier: 'meta-code',
ignoreSignature: true,
interactionCode: 'idx-interactionCode',
redirectUri: 'meta-redirectUri',
scopes: ['meta']
}, {
authorizeUrl: 'meta-authorizeUrl'
});
});
});
});
Loading

0 comments on commit 60e13da

Please sign in to comment.