Skip to content

Commit 227e88d

Browse files
authored
fix: managing Auth0 My Account API in resourceServers (#1229)
* fix: update dependencies to latest versions - package.json: bump winston to ^3.19.0 - package.json: bump @types/lodash to ^4.17.21 - package.json: bump typescript to ^5.9.3 * feat: enhance resource server handling - src/tools/auth0/handlers/resourceServers.ts: allow updating specific fields for system resource servers - src/tools/auth0/handlers/resourceServers.ts: sanitize fields of resource servers before returning - src/tools/auth0/handlers/resourceServers.ts: add updateResourceServer method to handle name exclusion for system servers * fix: remove from allowedKeys in ResourceServersHandler - src/tools/auth0/handlers/resourceServers.ts: removed 'token_lifetime_for_web' TODO - src/tools/auth0/handlers/resourceServers.ts: removed 'allow_offline_access' TODO * feat(test): add tests for Auth0 My Account API resource server handling - test/tools/auth0/handlers/resourceServers.tests.js: sanitize system resource servers in getType for Auth0 My Account API - test/tools/auth0/handlers/resourceServers.tests.js: update 'Auth0 My Account API' without name and is_system
1 parent bb95927 commit 227e88d

File tree

4 files changed

+150
-27
lines changed

4 files changed

+150
-27
lines changed

package-lock.json

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343
"promise-pool-executor": "^1.1.1",
4444
"sanitize-filename": "^1.6.3",
4545
"undici": "^7.16.0",
46-
"winston": "^3.18.3",
46+
"winston": "^3.19.0",
4747
"yargs": "^15.4.1"
4848
},
4949
"devDependencies": {
5050
"@types/fs-extra": "^9.0.13",
51-
"@types/lodash": "^4.17.20",
51+
"@types/lodash": "^4.17.21",
5252
"@types/mocha": "^10.0.10",
5353
"@types/nconf": "^0.10.7",
5454
"@typescript-eslint/parser": "^5.62.0",
@@ -71,7 +71,7 @@
7171
"sinon": "^13.0.2",
7272
"sinon-chai": "^3.7.0",
7373
"ts-mocha": "^10.1.0",
74-
"typescript": "^5.9.2",
74+
"typescript": "^5.9.3",
7575
"zlib": "^1.0.5"
7676
},
7777
"engines": {

src/tools/auth0/handlers/resourceServers.ts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
ApiResponse,
23
ResourceServer,
34
ResourceServerProofOfPossessionMechanismEnum,
45
ResourceServerSubjectTypeAuthorizationClientPolicyEnum,
@@ -92,8 +93,11 @@ export default class ResourceServersHandler extends DefaultHandler {
9293
...options,
9394
type: 'resourceServers',
9495
identifiers: ['id', 'identifier'],
95-
stripCreateFields: ['client_id'],
96+
stripCreateFields: ['client_id', 'is_system'],
9697
stripUpdateFields: ['identifier', 'client_id', 'is_system'],
98+
functions: {
99+
update: (args, data) => this.updateResourceServer(args, data),
100+
},
97101
});
98102
}
99103

@@ -104,13 +108,44 @@ export default class ResourceServersHandler extends DefaultHandler {
104108
async getType(): Promise<ResourceServer[]> {
105109
if (this.existing) return this.existing;
106110

107-
const resourceServers = await paginate<ResourceServer>(this.client.resourceServers.getAll, {
111+
let resourceServers = await paginate<ResourceServer>(this.client.resourceServers.getAll, {
108112
paginate: true,
109113
include_totals: true,
110114
});
111-
return resourceServers.filter(
115+
116+
resourceServers = resourceServers.filter(
112117
(rs) => rs.name !== constants.RESOURCE_SERVERS_MANAGEMENT_API_NAME
113118
);
119+
120+
// Sanitize resource servers fields
121+
const sanitizeResourceServersFields = (rs: ResourceServer[]): ResourceServer[] =>
122+
rs.map((resourceServer: ResourceServer) => {
123+
// For system resource servers like Auth0 My Account API, only allow certain fields to be updated
124+
if (resourceServer.is_system === true) {
125+
const allowedKeys = [
126+
'token_lifetime',
127+
'proof_of_possession',
128+
'skip_consent_for_verifiable_first_party_clients',
129+
'name',
130+
'identifier',
131+
'id',
132+
'is_system',
133+
];
134+
const sanitized: any = {};
135+
allowedKeys.forEach((key) => {
136+
if (key in resourceServer) {
137+
sanitized[key] = resourceServer[key];
138+
}
139+
});
140+
return sanitized;
141+
}
142+
143+
return resourceServer;
144+
});
145+
146+
this.existing = sanitizeResourceServersFields(resourceServers);
147+
148+
return this.existing;
114149
}
115150

116151
async calcChanges(assets: Assets): Promise<CalculatedChanges> {
@@ -159,4 +194,14 @@ export default class ResourceServersHandler extends DefaultHandler {
159194

160195
await super.validate(assets);
161196
}
197+
198+
async updateResourceServer(args, update: ResourceServer): Promise<ApiResponse<ResourceServer>> {
199+
// Exclude name from update as it cannot be modified for system resource servers like Auth0 My Account API
200+
if (update.is_system === true || update.name === 'Auth0 My Account API') {
201+
const { name, is_system: _isSystem, ...updateFields } = update;
202+
return this.client.resourceServers.update(args, updateFields);
203+
}
204+
205+
return this.client.resourceServers.update(args, update);
206+
}
162207
}

test/tools/auth0/handlers/resourceServers.tests.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,5 +621,83 @@ describe('#resourceServers handler', () => {
621621
expect(result[0]).to.have.property('name', 'someAPI');
622622
expect(result[0]).to.have.property('identifier', 'some-api');
623623
});
624+
625+
it('should sanitize system resource servers in getType for Auth0 My Account API', async () => {
626+
const systemResourceServer = {
627+
id: 'rs_system',
628+
identifier: 'https://api.system.com/me/',
629+
name: 'Auth0 My Account API',
630+
is_system: true,
631+
token_lifetime: 86400,
632+
scopes: [{ value: 'read:users' }], // Should be removed
633+
signing_alg: 'RS256', // Should be removed
634+
allow_offline_access: true, // Should be removed
635+
skip_consent_for_verifiable_first_party_clients: true,
636+
enforce_policies: true, // Should be removed
637+
token_dialect: 'access_token', // Should be removed
638+
};
639+
640+
const auth0 = {
641+
resourceServers: {
642+
getAll: (params) => mockPagedData(params, 'resourceServers', [systemResourceServer]),
643+
},
644+
pool,
645+
};
646+
647+
const handler = new resourceServers.default({ client: pageClient(auth0), config });
648+
const result = await handler.getType();
649+
650+
expect(result).to.be.an('array');
651+
expect(result[0]).to.deep.equal({
652+
id: 'rs_system',
653+
identifier: 'https://api.system.com/me/',
654+
name: 'Auth0 My Account API',
655+
is_system: true,
656+
token_lifetime: 86400,
657+
skip_consent_for_verifiable_first_party_clients: true,
658+
});
659+
});
660+
661+
it('should update "Auth0 My Account API" without name and is_system', async () => {
662+
let updateCalled = false;
663+
const existingResourceServer = {
664+
id: 'rs_my_account',
665+
identifier: 'https://auth0.com/my-account/me/',
666+
name: 'Auth0 My Account API',
667+
is_system: true,
668+
};
669+
670+
const auth0 = {
671+
resourceServers: {
672+
create: () => Promise.resolve({ data: [] }),
673+
update: function (params, data) {
674+
updateCalled = true;
675+
expect(params.id).to.equal('rs_my_account');
676+
expect(data.name).to.equal(undefined);
677+
expect(data.is_system).to.equal(undefined);
678+
expect(data.token_lifetime).to.equal(54321);
679+
return Promise.resolve({ data });
680+
},
681+
delete: () => Promise.resolve({ data: [] }),
682+
getAll: (params) => mockPagedData(params, 'resourceServers', [existingResourceServer]),
683+
},
684+
pool,
685+
};
686+
687+
const handler = new resourceServers.default({ client: pageClient(auth0), config });
688+
const stageFn = Object.getPrototypeOf(handler).processChanges;
689+
const data = {
690+
resourceServers: [
691+
{
692+
name: 'Auth0 My Account API',
693+
identifier: 'https://auth0.com/my-account/me/',
694+
token_lifetime: 54321,
695+
},
696+
],
697+
};
698+
699+
await stageFn.apply(handler, [data]);
700+
expect(updateCalled).to.equal(true);
701+
});
624702
});
625703
});

0 commit comments

Comments
 (0)