Skip to content

Commit

Permalink
Merge pull request #461 from vscheuber/main
Browse files Browse the repository at this point in the history
MINOR RELEASE
  • Loading branch information
vscheuber authored Nov 1, 2024
2 parents 491aa1d + 2b41925 commit c476cfb
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 28 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add governance API factory under `frodo.factory`:

- `generateGovernanceApi`: Generates a Governance Axios API instance

### Fixed

Fixes and improvements to imports and exports:

- Updated test timeouts from 90000 to 120000 milliseconds (to accommodate the bigger exports/imports in the future)
- Updated resource versions of different exports/imports to the latest ones
- Updated comments and type information to be more accurate and fix typos
- Fixed TrustedJWTIssuer exports/imports (since these will be included as part of the full config export/import in the future PR)
- Fixed service imports to work for federation services
- Updated exports for agents and esv secrets/variables to have a singular instead of plural type (i.e. `agents` => `agent`, `secrets` => `secret`, `variables` => `variable`). The reason for this is to make them more consistent with the rest of the exports which are also singular, and also because secrets plural will be used for exporting AM secret config in the future.
- For full exports, duplicate config is now deleted from the IDM exports since themes, email templates, and mappings are all handled separately.
- Fixed full imports to only import if the full import config contains the items being imported rather than erroring out.
- Fixed full imports to return the config items that were imported
- Fixed email template imports/exports. For exports, there was a bug with the api where not all email templates were being exported using “emailTemplate” as the type, but it was fixed by using “emailTemplat” as the type instead (not sure why this works, but it’s the best solution I could find to fix the problem).
- Moved functionality for handling env substitution and entity filters from CLI to lib for IDM exports/imports.
- Fixed a few bugs with importing/exporting journeys. The main issue that was found was that if you were importing a journey containing nodes that are not supported by the current deployment (e.g. IDM journey nodes from cloud being imported into a classic deployment of AM), the journey would still be imported. This would cause an error to be thrown on export of the journey preventing it as well as other journeys from being exported on full export. The fix here was to just prevent the import of the journey if this happens by erroring out to prevent those errors from happening on export.
- Fixed a few bugs with script imports to allow each of the 3 types of imports to work (i.e. if scripts are a single unencoded string, if scripts are a single encoded string, and if scripts are a decoded array).

## [2.2.1-0] - 2024-10-31

## [2.2.0] - 2024-10-10
Expand Down
123 changes: 100 additions & 23 deletions src/api/BaseApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ function getProxy(): AxiosProxyConfig | false {

/**
* Customize curlirize output
* @param request axios request object
* @param {object} params Params object
* @param params.request axios request object
* @param {State} params.state State object
*/
function curlirize(request, state: State) {
_curlirize(request, (result, err: Error | AxiosError) => {
Expand All @@ -117,10 +119,23 @@ function curlirize(request, state: State) {
err.response?.data['message']
? ' - ' + err.response?.data['message']
: ''
}${
err.response?.data['error']
? ' - ' + err.response?.data['error']
: ''
}${
err.response?.data['error_description']
? ' - ' + err.response?.data['error_description']
: ''
}`,
type: 'error',
state,
});
printMessage({
message: err.response?.headers ? err.response.headers : '',
type: 'error',
state,
});
} else {
// Just a stock error
printMessage({ message: err, type: 'error', state });
Expand All @@ -139,11 +154,13 @@ function curlirize(request, state: State) {

/**
* Generates an AM Axios API instance
* @param {ResourceConfig} resource Takes an object takes a resource object. example:
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either
* @param {object} params Params object
* @param {ResourceConfig} params.resource Takes an object takes a resource object. example:
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either
* add on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateAmApi({
resource,
Expand All @@ -153,7 +170,7 @@ export function generateAmApi({
resource: ResourceConfig;
requestOverride?: AxiosRequestConfig;
state: State;
}) {
}): AxiosInstance {
const headers = {
'User-Agent': userAgent,
'X-ForgeRock-TransactionId': transactionId,
Expand Down Expand Up @@ -200,11 +217,13 @@ export function generateAmApi({

/**
* Generates an OAuth2 Axios API instance
* @param {ResourceConfig} resource Resource config object.
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either
* @param {object} params Params object
* @param {ResourceConfig} params.resource Resource config object.
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either
* add on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateOauth2Api({
resource,
Expand All @@ -216,7 +235,7 @@ export function generateOauth2Api({
requestOverride?: AxiosRequestConfig;
authenticate?: boolean;
state: State;
}) {
}): AxiosInstance {
let headers: { [key: string]: any } = {
'User-Agent': userAgent,
'X-ForgeRock-TransactionId': transactionId,
Expand Down Expand Up @@ -268,18 +287,20 @@ export function generateOauth2Api({

/**
* Generates an IDM Axios API instance
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* @param {object} params Params object
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateIdmApi({
requestOverride = {},
state,
}: {
requestOverride?: AxiosRequestConfig;
state: State;
}) {
}): AxiosInstance {
const requestDetails = mergeDeep(
{
// baseURL: getTenantURL(storage.session.getTenant()),
Expand Down Expand Up @@ -312,18 +333,20 @@ export function generateIdmApi({

/**
* Generates a LogKeys API Axios instance
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* @param {object} params Params object
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateLogKeysApi({
requestOverride = {},
state,
}: {
requestOverride?: AxiosRequestConfig;
state: State;
}) {
}): AxiosInstance {
const headers = {
'User-Agent': userAgent,
'Content-Type': 'application/json',
Expand Down Expand Up @@ -355,18 +378,20 @@ export function generateLogKeysApi({

/**
* Generates a Log API Axios instance
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* @param {object} params Params object
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateLogApi({
requestOverride = {},
state,
}: {
requestOverride?: AxiosRequestConfig;
state: State;
}) {
}): AxiosInstance {
const headers = {
'User-Agent': userAgent,
'X-API-Key': state.getLogApiKey(),
Expand Down Expand Up @@ -396,11 +421,13 @@ export function generateLogApi({

/**
* Generates an Axios instance for the Identity Cloud Environment API
* @param {ResourceConfig} resource Resource config object.
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* @param {object} params Params object
* @param {ResourceConfig} params.resource Resource config object.
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateEnvApi({
resource,
Expand Down Expand Up @@ -441,12 +468,62 @@ export function generateEnvApi({
return request;
}

/**
* Generates an Axios instance for the Identity Cloud Governance API
* @param {object} params Params object
* @param {ResourceConfig} params.resource Resource config object.
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateGovernanceApi({
resource,
requestOverride = {},
state,
}: {
resource: ResourceConfig;
requestOverride?: AxiosRequestConfig;
state: State;
}): AxiosInstance {
const headers = {
'User-Agent': userAgent,
'Content-Type': 'application/json',
// only add API version if we have it
...(resource.apiVersion && { 'Accept-API-Version': resource.apiVersion }),
// only add authorization header if we have a bearer token
...(state.getBearerToken() && {
Authorization: `Bearer ${state.getBearerToken()}`,
}),
};
const requestDetails = {
timeout,
headers,
...requestOverride,
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
proxy: getProxy(),
};

const request = axios.create(requestDetails);

// enable curlirizer output in debug mode
if (state.getCurlirize()) {
curlirize(request, state);
}

return request;
}

/**
* Generates a release (Github or Npm) Axios API instance
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* @param {object} params Params object
* @param {AxiosRequestConfig} params.requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
* @param {State} params.state State object
*
* @returns {AxiosInstance}
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
export function generateReleaseApi({
baseUrl,
Expand Down
1 change: 1 addition & 0 deletions src/api/NodeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type NodeSkeleton = AmConfigEntityInterface & {
emailTemplateName?: string;
filteredProviders?: string[];
useScript?: boolean;
useFilterScript?: boolean;
};

export type NodeTypeSkeleton = IdObjectSkeletonInterface & {
Expand Down
19 changes: 19 additions & 0 deletions src/ops/ApiFactoryOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AxiosInstance, AxiosRequestConfig } from 'axios';
import {
generateAmApi,
generateEnvApi,
generateGovernanceApi,
generateIdmApi,
generateLogApi,
generateLogKeysApi,
Expand Down Expand Up @@ -74,6 +75,18 @@ export type ApiFactory = {
resource: ResourceConfig,
requestOverride?: AxiosRequestConfig
): AxiosInstance;
/**
* Generates an Axios instance for the Identity Cloud Governance API
* @param {ResourceConfig} resource Resource config object.
* @param {AxiosRequestConfig} requestOverride Takes an object of AXIOS parameters that can be used to either add
* on extra information or override default properties https://github.com/axios/axios#request-config
*
* @returns {AxiosInstance} Returns a reaady to use Axios instance
*/
generateGovernanceApi(
resource: ResourceConfig,
requestOverride?: AxiosRequestConfig
): AxiosInstance;
/**
* Generates a release (Github or Npm) Axios API instance
* @param {string} baseUrl Base URL for the request
Expand Down Expand Up @@ -123,6 +136,12 @@ export default (state: State): ApiFactory => {
): AxiosInstance {
return generateEnvApi({ resource, requestOverride, state });
},
generateGovernanceApi(
resource: ResourceConfig,
requestOverride?: AxiosRequestConfig
): AxiosInstance {
return generateGovernanceApi({ resource, requestOverride, state });
},
generateReleaseApi(
baseUrl: string,
requestOverride?: AxiosRequestConfig
Expand Down
4 changes: 4 additions & 0 deletions src/ops/JourneyOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,10 @@ const scriptedNodesConditions = {
return nodeConfig.useScript;
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
PingOneVerifyCompletionDecisionNode: (nodeConfig: NodeSkeleton): boolean => {
return nodeConfig.useFilterScript;
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
ScriptedDecisionNode: (_nodeConfig: NodeSkeleton): boolean => {
return true;
},
Expand Down
15 changes: 10 additions & 5 deletions src/ops/ScriptOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -759,11 +759,12 @@ export async function exportScripts({

/**
* Import scripts
* @param {string} scriptId Optional id of script. If supplied, only the script of that id is imported. Takes priority over scriptName if both are provided.
* @param {string} scriptName Optional name of script. If supplied, only the script of that name is imported
* @param {ScriptExportInterface} importData Script import data
* @param {ScriptImportOptions} options Script import options
* @param {boolean} validate If true, validates Javascript scripts to ensure no errors exist in them. Default: false
* @param {object} params Params object.
* @param {string} params.scriptId Optional id of script. If supplied, only the script of that id is imported. Takes priority over scriptName if both are provided.
* @param {string} params.scriptName Optional name of script. If supplied, only the script of that name is imported
* @param {ScriptExportInterface} params.importData Script import data
* @param {ScriptImportOptions} params.options Script import options
* @param {boolean} params.validate If true, validates Javascript scripts to ensure no errors exist in them. Default: false
* @returns {Promise<ScriptSkeleton[]>} the imported scripts
*/
export async function importScripts({
Expand Down Expand Up @@ -799,6 +800,10 @@ export async function importScripts({
((scriptId && scriptId !== scriptData._id) ||
(!scriptId && scriptName && scriptName !== scriptData.name));
if (isDefault || shouldNotImportScript) continue;
debugMessage({
message: `ScriptOps.importScripts: Importing script ${scriptData.name} (${existingId})`,
state,
});
let newId = existingId;
if (options.reUuid) {
newId = uuidv4();
Expand Down

0 comments on commit c476cfb

Please sign in to comment.