Skip to content

Commit

Permalink
fix: assert client_secret is present when required, require client_id…
Browse files Browse the repository at this point in the history
…, etc
  • Loading branch information
panva committed Sep 6, 2019
1 parent 87250d9 commit 82855a5
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 47 deletions.
8 changes: 8 additions & 0 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ module.exports = (issuer, aadIssValidation = false) => class Client extends Base
*/
constructor(metadata = {}, jwks) {
super();

if (typeof metadata.client_id !== 'string' || !metadata.client_id) {
throw new TypeError('client_id is required');
}

const properties = { ...CLIENT_DEFAULTS, ...metadata };

handleCommonMistakes(this, metadata, properties);
Expand Down Expand Up @@ -1015,6 +1020,9 @@ module.exports = (issuer, aadIssValidation = false) => class Client extends Base
* @api private
*/
async joseSecret(alg) {
if (!this.client_secret) {
throw new TypeError('client_secret is required');
}
if (/^A(\d{3})(?:GCM)?KW$/.test(alg)) {
return this.derivedKey(parseInt(RegExp.$1, 10));
}
Expand Down
14 changes: 13 additions & 1 deletion lib/helpers/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ async function clientAssertion(endpoint, payload) {
alg = Array.isArray(supported) && supported.find((signAlg) => algs.has(signAlg));
}

const keystore = instance(this).get('keystore');

if (!keystore) {
throw new TypeError('no client jwks provided for signing a client assertion with');
}

const key = instance(this).get('keystore').get({ alg, use: 'sig' });
if (!key) {
throw new TypeError(`no key found in client jwks to sign a client assertion with using alg ${alg}`);
Expand All @@ -53,6 +59,9 @@ async function authFor(endpoint, { clientAssertionPayload } = {}) {
case 'none':
return { body: { client_id: this.client_id } };
case 'client_secret_post':
if (!this.client_secret) {
throw new TypeError('client_secret_post client authentication method requires a client_secret');
}
return { body: { client_id: this.client_id, client_secret: this.client_secret } };
case 'private_key_jwt':
case 'client_secret_jwt': {
Expand All @@ -64,7 +73,7 @@ async function authFor(endpoint, { clientAssertionPayload } = {}) {
jti: random(),
iss: this.client_id,
sub: this.client_id,
aud: this.issuer[`${endpoint}_endpoint`],
aud: this.issuer[`${endpoint}_endpoint`], // TODO: pass the issuer instead
});

return {
Expand All @@ -83,6 +92,9 @@ async function authFor(endpoint, { clientAssertionPayload } = {}) {
// > Appendix B, and the encoded value is used as the username; the client
// > password is encoded using the same algorithm and used as the
// > password.
if (!this.client_secret) {
throw new TypeError('client_secret_basic client authentication method requires a client_secret');
}
const encoded = `${formUrlEncode(this.client_id)}:${formUrlEncode(this.client_secret)}`;
const value = Buffer.from(encoded).toString('base64');
return { headers: { Authorization: `Basic ${value}` } };
Expand Down
Loading

0 comments on commit 82855a5

Please sign in to comment.