Skip to content
Merged
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
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 36 additions & 15 deletions src/api/BaseApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if (process.env.FRODO_MOCK) {
const timeout = 30000;

// agentkeepalive
const maxSockets = 100;
const maxSockets = 500;
const maxFreeSockets = 10;
const keepAlive = false;

Expand Down Expand Up @@ -197,8 +197,11 @@ export function generateAmApi({
...headers,
...state.getAuthenticationHeaderOverrides(),
},
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
},
requestOverride
Expand Down Expand Up @@ -269,8 +272,11 @@ export function generateOauth2Api({
...headers,
...state.getAuthenticationHeaderOverrides(),
},
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
};

Expand Down Expand Up @@ -313,8 +319,11 @@ export function generateIdmApi({
Authorization: `Bearer ${state.getBearerToken()}`,
}),
},
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
},
requestOverride
Expand Down Expand Up @@ -401,8 +410,11 @@ export function generateLogApi({
// baseURL: getTenantURL(storage.session.getTenant()),
timeout,
headers,
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
},
requestOverride
Expand Down Expand Up @@ -489,8 +501,11 @@ export function generateEnvApi({
timeout,
headers,
...requestOverride,
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
};

Expand Down Expand Up @@ -537,8 +552,11 @@ export function generateGovernanceApi({
timeout,
headers,
...requestOverride,
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
};

Expand Down Expand Up @@ -578,8 +596,11 @@ export function generateReleaseApi({
'Content-Type': 'application/json',
},
...requestOverride,
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(false, false),
...(process.env.FRODO_MOCK !== 'record' &&
process.env.FRODO_POLLY_MODE !== 'record' && {
httpAgent: getHttpAgent(),
httpsAgent: getHttpsAgent(state.getAllowInsecureConnection()),
}),
proxy: getProxy(),
};

Expand Down
8 changes: 0 additions & 8 deletions src/api/ServiceApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ export async function putServiceNextDescendent({
globalConfig?: boolean;
state: State;
}): Promise<ServiceNextDescendent> {
// If performing an update (not create), idp updates will throw an HTTP 500 error unless the redirectAfterFormPostURI attribute has a value.
// If no redirectAfterFormPostURI is provided, importing with an empty string as its value will perform the same function without the 500 error.
if (
serviceId === 'SocialIdentityProviders' &&
serviceNextDescendentData.redirectAfterFormPostURI === undefined
) {
serviceNextDescendentData.redirectAfterFormPostURI = '';
}
const urlString = util.format(
serviceURLNextDescendentTemplate,
state.getHost(),
Expand Down
5 changes: 0 additions & 5 deletions src/api/SocialIdentityProvidersApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,6 @@ export async function putProviderByTypeAndId({
providerData: SocialIdpSkeleton;
state: State;
}) {
// If performing an update (not create), idp updates will throw an HTTP 500 error unless the redirectAfterFormPostURI attribute has a value.
// If no redirectAfterFormPostURI is provided, importing with an empty string as its value will perform the same function without the 500 error.
if (providerData.redirectAfterFormPostURI === undefined) {
providerData.redirectAfterFormPostURI = '';
}
// until we figure out a way to use transport keys in Frodo,
// we'll have to drop those encrypted attributes.
const cleanData = deleteDeepByKey(providerData, '-encrypted');
Expand Down
9 changes: 6 additions & 3 deletions src/ops/FrodoError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,15 @@ export class FrodoError extends Error {
case 'AxiosError':
{
combinedMessage += '\n HTTP client error';
combinedMessage += this.httpCode
? `\n Code: ${this.httpCode}`
combinedMessage += this.httpStatus
? `\n URL: ${error['config']['url']}`
: '';
combinedMessage += this.httpStatus
? `\n Status: ${this.httpStatus}`
: '';
combinedMessage += this.httpCode
? `\n Code: ${this.httpCode}`
: '';
combinedMessage += this.httpErrorText
? `\n Error: ${this.httpErrorText}`
: '';
Expand All @@ -91,7 +94,7 @@ export class FrodoError extends Error {
? `\n Message: ${this.httpMessage}`
: '';
combinedMessage += this.httpDetail
? `\n Detail: ${this.httpDetail}`
? `\n Detail: ${typeof this.httpDetail === 'object' ? JSON.stringify(this.httpDetail) : this.httpDetail}`
: '';
combinedMessage += this.httpDescription
? `\n Description: ${this.httpDescription}`
Expand Down
67 changes: 46 additions & 21 deletions src/ops/IdpOps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getScript, type ScriptSkeleton } from '../api/ScriptApi';
import { type ScriptSkeleton } from '../api/ScriptApi';
import {
deleteProviderByTypeAndId,
getSocialIdentityProviders as _getSocialIdentityProviders,
Expand All @@ -22,7 +22,7 @@ import {
import { getCurrentRealmName } from '../utils/ForgeRockUtils';
import { FrodoError } from './FrodoError';
import { type ExportMetaData } from './OpsTypes';
import { updateScript } from './ScriptOps';
import { readScript, updateScript } from './ScriptOps';

export type Idp = {
/**
Expand Down Expand Up @@ -480,22 +480,25 @@ export async function createSocialIdentityProvider({
providerType,
providerId,
providerData,
errorIfExists = true,
state,
}: {
providerType: string;
providerId: string;
providerData: SocialIdpSkeleton;
errorIfExists?: boolean;
state: State;
}): Promise<SocialIdpSkeleton> {
debugMessage({
message: `IdpOps.createSocialIdentityProvider: start`,
state,
});
let result: SocialIdpSkeleton;
try {
await readSocialIdentityProvider({ providerId, state });
result = await readSocialIdentityProvider({ providerId, state });
} catch (error) {
try {
const result = await updateSocialIdentityProvider({
result = await updateSocialIdentityProvider({
providerType,
providerId,
providerData,
Expand All @@ -513,9 +516,12 @@ export async function createSocialIdentityProvider({
);
}
}
throw new FrodoError(
`${getCurrentRealmName(state) + ' realm'} provider ${providerId} already exists`
);
if (errorIfExists) {
throw new FrodoError(
`${getCurrentRealmName(state) + ' realm'} provider ${providerId} already exists`
);
}
return result;
}

export async function updateSocialIdentityProvider({
Expand Down Expand Up @@ -547,11 +553,26 @@ export async function updateSocialIdentityProvider({
return response;
} catch (error) {
if (
error.response?.status === 500 &&
error.response?.data?.message ===
'Unable to update SMS config: Data validation failed for the attribute, Redirect after form post URL'
) {
providerData['redirectAfterFormPostURI'] = '';
try {
await _putProviderByTypeAndId({
type: providerType,
id: providerId,
providerData,
state,
});
} catch (importError2) {
throw new FrodoError(`Error updating provider ${providerId}`, error);
}
} else if (
error.response?.status === 400 &&
error.response?.data?.message === 'Invalid attribute specified.'
) {
const { validAttributes } = error.response.data.detail;
validAttributes.push('_id', '_type');
for (const attribute of Object.keys(providerData)) {
if (!validAttributes.includes(attribute)) {
if (state.getVerbose())
Expand All @@ -566,17 +587,21 @@ export async function updateSocialIdentityProvider({
}
if (state.getVerbose())
printMessage({ message: '\n', type: 'warn', newline: false, state });
const response = await _putProviderByTypeAndId({
type: providerType,
id: providerId,
providerData,
state,
});
debugMessage({
message: `IdpOps.updateSocialIdentityProvider: end (after retry)`,
state,
});
return response;
try {
const response = await _putProviderByTypeAndId({
type: providerType,
id: providerId,
providerData,
state,
});
debugMessage({
message: `IdpOps.updateSocialIdentityProvider: end (after retry)`,
state,
});
return response;
} catch (importError2) {
throw new FrodoError(`Error updating provider ${providerId}`, error);
}
} else {
// unhandleable error
throw new FrodoError(
Expand Down Expand Up @@ -696,7 +721,7 @@ export async function exportSocialIdentityProvider({
exportData.idp[idpData._id] = idpData;
if (idpData.transform) {
try {
const scriptData = await getScript({
const scriptData = await readScript({
scriptId: idpData.transform,
state,
});
Expand Down Expand Up @@ -750,7 +775,7 @@ export async function exportSocialIdentityProviders({
});
exportData.idp[idpData._id] = idpData;
if (options.deps && idpData.transform) {
const scriptData = await getScript({
const scriptData = await readScript({
scriptId: idpData.transform,
state,
});
Expand Down
4 changes: 2 additions & 2 deletions src/ops/JourneyOps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,12 @@ describe('JourneyOps', () => {
});
});

describe('getJourneys()', () => {
describe('readJourneys()', () => {
test('0: Method is implemented', async () => {
expect(JourneyOps.readJourneys).toBeDefined();
});

test('1: Get all journeys', async () => {
test('1: Read all journeys', async () => {
const journeys = await JourneyOps.readJourneys({ state });
expect(journeys).toMatchSnapshot();
});
Expand Down
Loading