Skip to content

Commit

Permalink
fix: url encode client_id returned in registration responses
Browse files Browse the repository at this point in the history
  • Loading branch information
panva committed Nov 17, 2022
1 parent 84e39b0 commit 500dfeb
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/actions/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const validateRegistrationAccessToken = [
);
ctx.assert(regAccessToken, new InvalidToken('token not found'));

const client = await ctx.oidc.provider.Client.find(ctx.params.clientId);
const client = await ctx.oidc.provider.Client.find(decodeURIComponent(ctx.params.clientId));

if (!client || client.clientId !== regAccessToken.clientId) {
await regAccessToken.destroy();
Expand Down Expand Up @@ -139,7 +139,7 @@ module.exports = {
if (rat) {
Object.assign(ctx.body, {
registration_client_uri: ctx.oidc.urlFor('client', {
clientId: properties.client_id,
clientId: encodeURIComponent(properties.client_id),
}),
registration_access_token: await rat.save(),
});
Expand Down
22 changes: 22 additions & 0 deletions test/client_id_uri/client_id_uri.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const cloneDeep = require('lodash/cloneDeep');
const merge = require('lodash/merge');

const nanoid = require('../../lib/helpers/nanoid');
const config = cloneDeep(require('../default.config'));

merge(config.features, {
registration: {
enabled: true,
rotateRegistrationAccessToken: false,
idFactory() {
return new URL(`https://repo.clients.com/path?id=${nanoid()}`).href;
},
},
registrationManagement: {
enabled: true,
},
});

module.exports = {
config,
};
59 changes: 59 additions & 0 deletions test/client_id_uri/client_id_uri.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const { expect } = require('chai');

const bootstrap = require('../test_helper');

describe('registration management with client_id as URI', () => {
before(bootstrap(__dirname));

it('returns client_id as a URI string', async function () {
let client_id;
let registration_client_uri;
let registration_access_token;

await this.agent.post('/reg')
.send({
redirect_uris: ['https://client.example.com/cb'],
})
.expect(201)
.expect((response) => {
({ client_id, registration_access_token, registration_client_uri } = response.body);

const parsed = new URL(registration_client_uri);
expect(parsed.search).to.be.empty;
const i = parsed.pathname.indexOf('/reg/');
expect(parsed.pathname.slice(i + 5)).to.equal(encodeURIComponent(client_id));
});

await this.agent.get(new URL(registration_client_uri).pathname)
.auth(registration_access_token, { type: 'bearer' })
.expect(200)
.expect((response) => {
({ registration_client_uri } = response.body);

const parsed = new URL(registration_client_uri);
expect(parsed.search).to.be.empty;
const i = parsed.pathname.indexOf('/reg/');
expect(parsed.pathname.slice(i + 5)).to.equal(encodeURIComponent(client_id));
});

await this.agent.put(new URL(registration_client_uri).pathname)
.auth(registration_access_token, { type: 'bearer' })
.send({
client_id,
redirect_uris: ['https://client.example.com/cb2'],
})
.expect(200)
.expect((response) => {
({ registration_client_uri } = response.body);

const parsed = new URL(registration_client_uri);
expect(parsed.search).to.be.empty;
const i = parsed.pathname.indexOf('/reg/');
expect(parsed.pathname.slice(i + 5)).to.equal(encodeURIComponent(client_id));
});

await this.agent.delete(new URL(registration_client_uri).pathname)
.auth(registration_access_token, { type: 'bearer' })
.expect(204);
});
});

0 comments on commit 500dfeb

Please sign in to comment.