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

new experimental ea command flag #1027

Merged
merged 12 commits into from
Feb 6, 2025
8 changes: 8 additions & 0 deletions docs/using-as-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Boolean. Enables more verbose error logging; useful during troubleshooting. Defa

A url for proxying requests. Only set this if you are behind a proxy.

### `--experimental_ea`

Boolean. When enabled, gain early access Auth0 resources support and experimental features. Default: `false`.

### Examples

```shell
Expand Down Expand Up @@ -71,6 +75,10 @@ A url for proxying requests. Only set this if you are behind a proxy.

Boolean. Enables more verbose error logging; useful during troubleshooting. Default: `false`.

### `--experimental_ea`

Boolean. When enabled, gain early access Auth0 resources support and experimental features. Default: `false`.

### Examples

```shell
Expand Down
6 changes: 6 additions & 0 deletions src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type SharedParams = {
secret?: string;
base_path?: string; // Necessary when package imported as Node module
config?: Partial<Config>;
experimental_ea?: boolean;
};

type ImportSpecificParams = {
Expand Down Expand Up @@ -43,6 +44,11 @@ function getParams(): CliParams {
describe: 'A url for proxying requests, only set this if you are behind a proxy.',
type: 'string',
})
.option('experimental_ea', {
describe: 'This will enable supoort experimental early access of features/resource types.',
type: 'boolean',
default: false,
})
.command(['import', 'deploy'], 'Deploy Configuration', {
input_file: {
alias: 'i',
Expand Down
9 changes: 9 additions & 0 deletions src/commands/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default async function exportCMD(params: ExportParams) {
export_ids: exportIds,
secret: clientSecret,
env: shouldInheritEnv = false,
experimental_ea: experimentalEA,
} = params;

if (shouldInheritEnv) {
Expand Down Expand Up @@ -44,6 +45,14 @@ export default async function exportCMD(params: ExportParams) {
overrides.AUTH0_EXPORT_IDENTIFIERS = exportIds;
}

// Overrides AUTH0_INCLUDE_EXPERIMENTAL_EA is experimental_ea passed in command line
if (experimentalEA) {
overrides.AUTH0_EXPERIMENTAL_EA = experimentalEA;

// nconf.overrides() sometimes doesn't work, so we need to set it manually to ensure it's set
nconf.set('AUTH0_EXPERIMENTAL_EA', experimentalEA);
}

// Check output folder
if (!isDirectory(outputFolder)) {
log.info(`Creating ${outputFolder}`);
Expand Down
9 changes: 9 additions & 0 deletions src/commands/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default async function importCMD(params: ImportParams) {
config: configObj,
env: shouldInheritEnv = false,
secret: clientSecret,
experimental_ea: experimentalEA,
} = params;

if (shouldInheritEnv) {
Expand All @@ -39,6 +40,14 @@ export default async function importCMD(params: ImportParams) {
overrides.AUTH0_CLIENT_SECRET = clientSecret;
}

// Overrides AUTH0_INCLUDE_EXPERIMENTAL_EA is experimental_ea passed in command line
if (experimentalEA) {
overrides.AUTH0_EXPERIMENTAL_EA = experimentalEA;

// nconf.overrides() sometimes doesn't work, so we need to set it manually to ensure it's set
nconf.set('AUTH0_EXPERIMENTAL_EA', experimentalEA);
}

nconf.overrides(overrides);

// Setup context and load
Expand Down
19 changes: 19 additions & 0 deletions src/context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const nonPrimitiveProps: (keyof Config)[] = [
'INCLUDED_PROPS',
];

const EA_FEATURES = ['ACUL'];

export const setupContext = async (
config: Config,
command: 'import' | 'export'
Expand Down Expand Up @@ -132,6 +134,23 @@ export const setupContext = async (
}
})(config);

((config: Config) => {
// Check if experimental early access features are enabled
if (config.AUTH0_EXPERIMENTAL_EA) {
log.warn(
`Experimental early access ${
EA_FEATURES.length === 1
? 'feature [' + EA_FEATURES.join('') + '] is'
: 'features [' + EA_FEATURES.join(',') + '] are'
} enabled. These are in a pre-release state and may change in future release.`
);
} else {
log.info(
'To enable experimental early access features use --experimental_ea flag or set AUTH0_EXPERIMENTAL_EA=true in configuration JSON.'
);
}
})(config);

const accessToken = await (async (): Promise<string> => {
const {
AUTH0_DOMAIN,
Expand Down
24 changes: 16 additions & 8 deletions src/tools/auth0/handlers/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,15 @@ export default class PromptsHandler extends DefaultHandler {
partials,
};

try {
const screenRenderers = await this.getPromptScreenSettings();
prompts.screenRenderers = screenRenderers;
} catch (error) {
log.warn(`Unable to fetch screen renderers: ${error}`);
const includeExperimentalEA = this.config('AUTH0_EXPERIMENTAL_EA') || false;

if (includeExperimentalEA) {
try {
const screenRenderers = await this.getPromptScreenSettings();
prompts.screenRenderers = screenRenderers;
} catch (error) {
log.warn(`Unable to fetch screen renderers: ${error}`);
}
}

return prompts;
Expand Down Expand Up @@ -527,8 +531,12 @@ export default class PromptsHandler extends DefaultHandler {
await this.updateCustomTextSettings(customText);
await this.updateCustomPromptsPartials(partials);

// Update screen renderers
await this.updateScreenRenderers(screenRenderers);
const includeExperimentalEA = this.config('AUTH0_EXPERIMENTAL_EA') || false;

if (includeExperimentalEA) {
// Update screen renderers
await this.updateScreenRenderers(screenRenderers);
}

this.updated += 1;
this.didUpdate(prompts);
Expand Down Expand Up @@ -608,7 +616,7 @@ export default class PromptsHandler extends DefaultHandler {
} else {
updatePayload = {
...updatePrams,
rendering_mode
rendering_mode,
};
}

Expand Down
4 changes: 4 additions & 0 deletions src/tools/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ const constants = {
'email-identifier-challenge': ['email-identifier-challenge'],
passkeys: ['passkey-enrollment', 'passkey-enrollment-local'],
captcha: ['interstitial-captcha'],
login: ['login'],
signup: ['signup'],
'reset-password': ['reset-password-request', 'reset-password-email', 'reset-password', 'reset-password-success', 'reset-password-error'],

} as PromptScreenMapping,
};

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export type Config = {
AUTH0_EXCLUDED_CONNECTIONS?: string[];
AUTH0_EXCLUDED_RESOURCE_SERVERS?: string[];
AUTH0_EXCLUDED_DEFAULTS?: string[];
AUTH0_EXPERIMENTAL_EA: boolean;
}; // TODO: replace with a more accurate representation of the Config type

export type Asset = { [key: string]: any };
Expand Down
41 changes: 41 additions & 0 deletions test/configFactory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect } from 'chai';
import { configFactory, ConfigFunction } from '../src/configFactory';
import { Config } from '../src/types';

describe('configFactory', () => {
let config: ReturnType<typeof configFactory>;

beforeEach(() => {
config = configFactory();
});

it('should set and get configuration values', () => {
config.setValue('someKey' as keyof Config, 'someValue');
expect(config('someKey' as keyof Config)).to.equal('someValue');
});

it('should throw an error if no provider is set and key is not in settings', () => {
expect(() => config('someKey' as keyof Config)).to.throw(
'A configuration provider has not been set'
);
});

it('should use the provider function to get configuration values', () => {
const providerFunction: ConfigFunction = (key) => {
if ((key as string) === 'someKey') return 'providedValue';
return null;
};
config.setProvider(providerFunction);
expect(config('someKey' as keyof Config)).to.equal('providedValue');
});

it('should prioritize settings over provider function', () => {
config.setValue('someKey' as keyof Config, 'someValue');
const providerFunction: ConfigFunction = (key) => {
if ((key as string) === 'someKey') return 'providedValue';
return null;
};
config.setProvider(providerFunction);
expect(config('someKey' as keyof Config)).to.equal('someValue');
});
});
Loading