Skip to content

Commit

Permalink
Enabling keyword preservation for wider array of resources (#864)
Browse files Browse the repository at this point in the history
* Initial attempt

* Pulling in fix from @brendenpalmer and adding test case

* Removing console log

* Removing extraneous test

* Adding pages test case too

* Reverting changes to client grants, better suited for other PR

* Add a failing test demonstrating bug with preserving keywords within `guardianFactorProviders`

* Potential idea for a fix

---------

Co-authored-by: Will Vedder <[email protected]>
Co-authored-by: Brenden Palmer <[email protected]>
Co-authored-by: Sergiu Ghitea <[email protected]>
  • Loading branch information
4 people authored Nov 22, 2023
1 parent 672094d commit 9e25d55
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 18 deletions.
38 changes: 21 additions & 17 deletions src/keywordPreservation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const doesHaveKeywordMarker = (
export const getPreservableFieldsFromAssets = (
asset: object,
keywordMappings: KeywordMappings,
resourceSpecificIdentifiers: Partial<{ [key in AssetTypes]: string | string[] }>,
resourceSpecificIdentifiers: Partial<Record<AssetTypes, string | string[]>>,
address = ''
): string[] => {
if (typeof asset === 'string') {
Expand All @@ -41,20 +41,26 @@ export const getPreservableFieldsFromAssets = (
return asset
.map((arrayItem) => {
const resourceIdentifiers: string[] = (() => {
const identifiers = resourceSpecificIdentifiers[address];
if (Array.isArray(identifiers)) {
return identifiers;
const identifierOrIdentifiers = resourceSpecificIdentifiers[address as AssetTypes];

if (Array.isArray(identifierOrIdentifiers)) {
return identifierOrIdentifiers;
}

if (identifierOrIdentifiers === undefined) {
return [];
}
return [identifiers];

return [identifierOrIdentifiers];
})();

const specificAddress = resourceIdentifiers.reduce(
(aggregateAddress, resourceIdentifier) => {
resourceSpecificIdentifiers[address];
if (resourceIdentifier === undefined) return null; // See if this specific resource type has an identifier
if (resourceIdentifier === undefined) return ''; // See if this specific resource type has an identifier

const identifierFieldValue = arrayItem[resourceIdentifier];
if (identifierFieldValue === undefined) return null; // See if this specific array item possess the resource-specific identifier
if (identifierFieldValue === undefined) return ''; // See if this specific array item possess the resource-specific identifier

if (aggregateAddress === '') {
return `${resourceIdentifier}=${identifierFieldValue}`;
Expand All @@ -65,7 +71,7 @@ export const getPreservableFieldsFromAssets = (
''
);

if (specificAddress === null) {
if (specificAddress.length === 0) {
return [];
}

Expand Down Expand Up @@ -227,15 +233,13 @@ export const preserveKeywords = ({
}): object => {
if (Object.keys(keywordMappings).length === 0) return remoteAssets;

const resourceSpecificIdentifiers: Partial<{ [key in AssetTypes]: string[] }> =
auth0Handlers.reduce((acc, handler): Partial<{ [key in AssetTypes]: string[] }> => {
return {
...acc,
[handler.type]: handler.identifiers.filter((identifiers) => {
return identifiers !== handler.id;
})[0],
};
}, {});
const resourceSpecificIdentifiers: Partial<Record<AssetTypes, string[]>> = auth0Handlers.reduce(
(acc, handler) => {
acc[handler.type] = handler.identifiers.flat();
return acc;
},
{}
);

const addresses = getPreservableFieldsFromAssets(
localAssets,
Expand Down
83 changes: 82 additions & 1 deletion test/keywordPreservation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,22 @@ describe('preserveKeywords', () => {
status: 'ready',
},
],
guardianFactorProviders: [
{
name: 'sms',
auth_token: '##AUTH_TOKEN##',
from: '##COMPANY_NAME##',
sid: '##TWILIO_SID##',
messaging_service_sid: '##TWILIO_SID##',
provider: 'twilio',
},
],
pages: [
{
name: 'error_page',
url: '##URL##/error',
},
],
};

const mockRemoteAssets = {
Expand All @@ -505,7 +521,6 @@ describe('preserveKeywords', () => {
universal_login_enabled: true,
customText: {},
},
pages: undefined, //TODO: test these cases more thoroughly
rules: null, //TODO: test these cases more thoroughly
connections: [], // Empty on remote but has local assets
actions: [
Expand Down Expand Up @@ -537,6 +552,22 @@ describe('preserveKeywords', () => {
status: 'ready',
},
],
guardianFactorProviders: [
{
name: 'sms',
auth_token: 'mock-twilio-auth-token',
from: 'travel0',
sid: 'twilio-sid',
messaging_service_sid: 'twilio-sid',
provider: 'twilio',
},
],
pages: [
{
name: 'error_page',
url: 'https://travel0.com/error',
},
],
};

const auth0Handlers = [
Expand All @@ -561,6 +592,8 @@ describe('preserveKeywords', () => {
type: 'resourceServers',
},
{ id: 'id', identifiers: ['id', 'domain'], type: 'customDomains' },
{ id: 'name', identifiers: ['id', 'name'], type: 'guardianFactorProviders' },
{ id: 'id', identifiers: ['name'], type: 'pages' },
];

it('should preserve keywords when they correlate to keyword mappings', () => {
Expand All @@ -569,9 +602,12 @@ describe('preserveKeywords', () => {
remoteAssets: mockRemoteAssets,
keywordMappings: {
COMPANY_NAME: 'Travel0',
URL: 'https://trave0.com',
ALLOWED_LOGOUT_URLS: ['localhost:3000/logout', 'https://travel0.com/logout'],
ENV: 'Production',
API_MAIN_IDENTIFIER: 'https://travel0.com/api/v1',
AUTH_TOKEN: 'mock-twilio-auth-token',
TWILIO_SID: 'twilio-sid',
},
auth0Handlers,
});
Expand All @@ -590,6 +626,11 @@ describe('preserveKeywords', () => {
},
];
expected.customDomains[0].domain = '##COMPANY_NAME##.com';
expected.guardianFactorProviders[0].sid = '##TWILIO_SID##';
expected.guardianFactorProviders[0].messaging_service_sid = '##TWILIO_SID##';
expected.guardianFactorProviders[0].auth_token = '##AUTH_TOKEN##';
expected.guardianFactorProviders[0].from = '##COMPANY_NAME##';
expected.pages[0].url = '##URL##/error';
return expected;
})()
);
Expand Down Expand Up @@ -883,4 +924,44 @@ describe('preserveKeywords', () => {
connections: null,
});
});

it('`guardianFactorProviders` should have fields preserved', () => {
const preservedAssets = preserveKeywords({
localAssets: {
guardianFactorProviders: [
{
auth_token: '##AUTH_TOKEN##',
name: 'sms',
},
],
},
remoteAssets: {
guardianFactorProviders: [
{
auth_token: 'auth_token',
name: 'sms',
},
],
},
keywordMappings: {
AUTH_TOKEN: 'auth_token',
},
auth0Handlers: [
{
id: 'name',
identifiers: ['id', 'name'],
type: 'guardianFactorProviders',
},
],
});

expect(preservedAssets).to.deep.equal({
guardianFactorProviders: [
{
auth_token: '##AUTH_TOKEN##',
name: 'sms',
},
],
});
});
});

0 comments on commit 9e25d55

Please sign in to comment.