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

feat(idx): include options in input scope - OKTA-486667 #1189

Closed
Closed
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
### Features

- [#1186](https://github.com/okta/okta-auth-js/pull/1186) Supports `maxAge` param in interaction code flow. This parameter can be passed in from either SDK level options or `idx.interact` options.
- [#1189](https://github.com/okta/okta-auth-js/pull/1189) IDX: includes `options` field in `inputs` scope, and deprecated top level `options` from `nextStep` field of the response (removal will happen in the next major version).

### Fixes

- [#1189](https://github.com/okta/okta-auth-js/pull/1189) IDX: fixes `input` type indicator's field name for `username` and `authenticator`. Before the indicator was named as `key`, now it's fixed to `type` to follow input metadata with all other inputs.

## 6.4.3

Expand Down
4 changes: 3 additions & 1 deletion docs/idx.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ This field contains information to proceed with the next step. It's available wh
const transaction = await authClient.idx.authenticate({ username: 'from user input' });
```

- `options?`: This field is available in response when the input is a selection. It can also provide information for how to build UI for the next step.
- `options?` (**deprecated**):
**warning: This field has been deprecated and will be removed in the next major version (v7). Current options can still be found within related input's scope.**
This field is available in response when the input is a selection. It can also provide information for how to build UI for the next step.
###### `tokens?`
Expand Down
11 changes: 7 additions & 4 deletions lib/idx/remediators/AuthenticatorEnrollmentData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ export class AuthenticatorEnrollmentData extends AuthenticatorData<Authenticator
};
}

getInputAuthenticator() {
getInputAuthenticator(remediation) {
return [
{ name: 'methodType', type: 'string', required: true },
{ name: 'phoneNumber', type: 'string', required: true, label: 'Phone Number' },
];
{ name: 'methodType', type: 'string' },
{ name: 'phoneNumber', label: 'Phone Number', type: 'string' }
].map(item => {
const value = remediation.form.value.find(val => val.name === item.name);
return { ...value, ...item };
});
}

protected mapAuthenticatorDataFromValues(data?) {
Expand Down
7 changes: 6 additions & 1 deletion lib/idx/remediators/AuthenticatorVerificationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ export class AuthenticatorVerificationData extends AuthenticatorData<Authenticat
const methodType = authenticator.form!.value.find(({ name }) => name === 'methodType');
// if has methodType in form, let user select the methodType
if (methodType && methodType.options) {
return { name: 'methodType', type: 'string', required: true };
return {
name: 'methodType',
type: 'string',
required: true,
options: methodType.options
};
}
// no methodType, then return form values
const inputs = [...authenticator.form!.value];
Expand Down
1 change: 1 addition & 0 deletions lib/idx/remediators/Base/AuthenticatorData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class AuthenticatorData<T extends AuthenticatorDataValues = Authenticator
.some(data => compareAuthenticators(this.authenticator, data));
}

// TODO: remove this override method in the next major version - OKTA-491236
getNextStep() {
const common = super.getNextStep();
const options = this.getMethodTypes();
Expand Down
11 changes: 9 additions & 2 deletions lib/idx/remediators/Base/SelectAuthenticator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export class SelectAuthenticator<T extends SelectAuthenticatorValues = SelectAut
return false;
}

// TODO: remove this override method in the next major version - OKTA-491236
getNextStep() {
const common = super.getNextStep();
const authenticatorFromRemediation = getAuthenticatorFromRemediation(this.remediation);
Expand Down Expand Up @@ -96,8 +97,14 @@ export class SelectAuthenticator<T extends SelectAuthenticatorValues = SelectAut
};
}

getInputAuthenticator() {
return { name: 'authenticator', key: 'string' };
getInputAuthenticator(remediation) {
const options = remediation.options.map(({ label, relatesTo }) => {
return {
label,
value: relatesTo.key
};
});
return { name: 'authenticator', type: 'string', options };
}

getValuesAfterProceed(): T {
Expand Down
2 changes: 1 addition & 1 deletion lib/idx/remediators/SelectAuthenticatorUnlockAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class SelectAuthenticatorUnlockAccount extends SelectAuthenticator<Select
}

getInputUsername () {
return { name: 'username', key: 'string' };
return { name: 'username', type: 'string' };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a fix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh, yes, will add to the changelog

}

}
1 change: 1 addition & 0 deletions lib/idx/remediators/SelectEnrollmentChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class SelectEnrollmentChannel extends Remediator<SelectEnrollmentChannelV
const authenticator = context.currentAuthenticator.value;
return {
...common,
// TODO: remove options field in the next major version - OKTA-491236
...(options && { options }),
authenticator,
};
Expand Down
2 changes: 1 addition & 1 deletion scripts/e2e-express-embedded-auth-with-sdk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export DBUS_SESSION_BUS_ADDRESS=/dev/null

# Configuration
# Remember to set this while running tests locally
export MAX_INSTANCES=3
export MAX_INSTANCES=2
export SAMPLE_NAME=@okta/samples.express-embedded-auth-with-sdk
export ORG_OIE_ENABLED=true
export USERNAME=mary@acme.com
Expand Down
4 changes: 3 additions & 1 deletion test/apps/react-oie/src/components/FlowPage/FlowPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ const FlowPage = () => {
}, [flow, transaction, startFlow]);

const backToHomePage = async () => {
// clear `flow` param to break the transaction update loop
history.replace('/');

await oktaAuth.idx.cancel();
setTransaction(null);
history.replace('/');
};

const getFormComponent = () => {
Expand Down
8 changes: 4 additions & 4 deletions test/apps/react-oie/src/components/GeneralForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const GeneralForm = () => {
const canRecoverPassword = !!actions?.['currentAuthenticator-recover'];
const idps = availableSteps.filter(step => step.name === 'redirect-idp');
const form = formTransformer(nextStep)({} /* initial form value */);
const { inputs, select, text, image } = form;
const { inputs, selects, text, image } = form;

return (
<Box padding="m">
Expand All @@ -82,14 +82,14 @@ const GeneralForm = () => {
<Form.Main>
{text && <div>{text.value}</div>}
{image && <img src={image.src} />}
{select && (
<Select label={select.label} name={select.name} onChange={handleChange}>
{selects && selects.map(select => (
<Select key={select.name} label={select.label} name={select.name} onChange={handleChange}>
<Select.Option key="" value="">---</Select.Option>
{select.options.map(({ key, label }) => (
<Select.Option key={key} value={key}>{label}</Select.Option>
))}
</Select>
)}
))}
{inputs && inputs.map((input) => {
const { label, name, type, required } = input;
const Comp = type === 'checkbox' ? Checkbox : TextInput;
Expand Down
24 changes: 13 additions & 11 deletions test/apps/react-oie/src/formTransformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ const inputTransformer = nextStep => form => {
};

const selectTransformer = nextStep => form => {
const { inputs, options } = nextStep;
const { inputs } = nextStep;

if (!options) {
return form;
}

return {
...form,
select: {
name: inputs[0].name,
options: options.map(({ label, value }) => ({ key: value, value, label }))
return inputs.reduce((acc, { name, options }) => {
if (!options) {
return acc;
}
};
if (!acc.selects) {
acc.selects = [];
}
acc.selects.push({
name,
options: options.map(({ label, value }) => ({ key: value, value, label }))
});
return acc;
}, form);
};

const securityQuestionTransformer = nextStep => form => {
Expand Down
48 changes: 42 additions & 6 deletions test/spec/idx/authenticate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ describe('idx/authenticate', () => {
name: 'identify',
inputs: [{
name: 'username',
label: 'Username'
label: 'Username',
}]
});

Expand All @@ -444,8 +444,12 @@ describe('idx/authenticate', () => {
value: 'okta_password'
}],
inputs: [{
key: 'string',
name: 'authenticator'
type: 'string',
name: 'authenticator',
options: [{
label: 'Password',
value: 'okta_password'
}]
}]
});

Expand Down Expand Up @@ -712,7 +716,15 @@ describe('idx/authenticate', () => {
type: 'phone',
},
inputs: [
{ name: 'methodType', type: 'string', required: true }
{
name: 'methodType',
type: 'string',
required: true,
options: [
{ label: 'SMS', value: 'sms' },
{ label: 'Voice call', value: 'voice' },
]
}
],
options: [
{ label: 'SMS', value: 'sms' },
Expand Down Expand Up @@ -976,7 +988,15 @@ describe('idx/authenticate', () => {
type: 'phone',
},
inputs: [
{ name: 'methodType', type: 'string', required: true },
{
name: 'methodType',
type: 'string',
required: true,
options: [
{ label: 'SMS', value: 'sms' },
{ label: 'Voice call', value: 'voice' },
]
},
{ name: 'phoneNumber', type: 'string', required: true, label: 'Phone Number' },
],
options: [
Expand Down Expand Up @@ -1066,7 +1086,15 @@ describe('idx/authenticate', () => {
type: 'phone',
},
inputs: [
{ name: 'methodType', type: 'string', required: true },
{
name: 'methodType',
type: 'string',
required: true,
options: [
{ label: 'SMS', value: 'sms' },
{ label: 'Voice call', value: 'voice' }
],
},
{ name: 'phoneNumber', type: 'string', required: true, label: 'Phone Number' },
],
options: [
Expand Down Expand Up @@ -2095,6 +2123,14 @@ describe('idx/authenticate', () => {
expect(verifyPasswordResponse.proceed).toHaveBeenCalledWith('challenge-authenticator', expect.any(Object));
expect(response.nextStep).toMatchObject({
name: 'select-authenticator-enroll',
inputs: [{
name: 'authenticator',
type: 'string',
options: [{
label: 'Email',
value: AuthenticatorKey.OKTA_EMAIL
}],
}],
options: [{
label: 'Email',
value: AuthenticatorKey.OKTA_EMAIL
Expand Down
20 changes: 18 additions & 2 deletions test/spec/idx/recoverPassword.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,15 @@ describe('idx/recoverPassword', () => {
nextStep: {
name: 'select-authenticator-authenticate',
inputs: [
{ key: 'string', name: 'authenticator' }
{
type: 'string',
name: 'authenticator',
options: [
{ label: 'Okta Verify', value: 'okta_verify' },
{ label: 'Phone', value: 'phone_number' },
{ label: 'Email', value: 'okta_email' }
]
}
],
options: [
{ label: 'Okta Verify', value: 'okta_verify' },
Expand Down Expand Up @@ -530,7 +538,15 @@ describe('idx/recoverPassword', () => {
nextStep: {
name: 'select-authenticator-authenticate',
inputs: [
{ key: 'string', name: 'authenticator' }
{
type: 'string',
name: 'authenticator',
options: [
{ label: 'Okta Verify', value: 'okta_verify' },
{ label: 'Phone', value: 'phone_number' },
{ label: 'Email', value: 'okta_email' }
]
}
],
options: [
{ label: 'Okta Verify', value: 'okta_verify' },
Expand Down
Loading