X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=lib%2Fcommunication.js;h=2a69e34df0fe4f150f8b2548a131ae0ca2391ddd;hb=e486f80a4e7a1f65498335e7408f3301c9e7cb44;hp=d52d784690917d503e852309f4256650cfc4c60e;hpb=30851a8cb9f8823b1b395ace8f53d62c5c53abd8;p=squeep-indieauth-helper diff --git a/lib/communication.js b/lib/communication.js index d52d784..2a69e34 100644 --- a/lib/communication.js +++ b/lib/communication.js @@ -2,7 +2,6 @@ const axios = require('axios'); const { mf2 } = require('microformats-parser'); -const { base64ToBase64URL } = require('@squeep/base64url'); const { parse: parseLinkHeader } = require('@squeep/web-linking'); const { Iconv } = require('iconv'); const { version: packageVersion, name: packageName } = require('../package.json'); @@ -61,7 +60,7 @@ class Communication { static _challengeFromVerifier(verifier) { const hash = createHash('sha256'); hash.update(verifier); - return base64ToBase64URL(hash.digest('base64')); + return hash.digest('base64url'); } @@ -73,7 +72,7 @@ class Communication { */ /** * Create a code verifier and its challenge. - * @param {Number} length + * @param {Number} length of verifier string, between 43 and 128 * @returns {Promise} */ static async generatePKCE(length = 128) { @@ -83,7 +82,7 @@ class Communication { const bufferLength = Math.floor(length * 3 / 4); const randomBuffer = await randomBytesAsync(bufferLength); - const verifier = base64ToBase64URL(randomBuffer.toString('base64')); + const verifier = randomBuffer.toString('base64url'); const challenge = Communication._challengeFromVerifier(verifier); @@ -219,9 +218,10 @@ class Communication { /** - * Parse and add any header link relations to mf data. + * Parse and add any header link relations from response to microformat data. * @param {Object} microformat * @param {Object} response + * @param {Object} response.headers */ _mergeLinkHeader(microformat, response) { const _scope = _fileScope('_mergeLinkHeader'); @@ -749,8 +749,8 @@ class Communication { /** - * POST to the auth endpoint, to redeem a code for a profile object. - * FIXME: [name] this isn't specific to profile redemption, it works for tokens too + * POST to the auth endpoint, to redeem a code for a profile or token. + * N.B. this absorbs any errors! * @param {URL} urlObj * @param {String} code * @param {String} codeVerifier @@ -758,8 +758,8 @@ class Communication { * @param {String} redirectURI * @returns {Object} */ - async redeemProfileCode(urlObj, code, codeVerifier, clientId, redirectURI) { - const _scope = _fileScope('redeemProfileCode'); + async redeemCode(urlObj, code, codeVerifier, clientId, redirectURI) { + const _scope = _fileScope('redeemCode'); const formData = common.formData({ 'grant_type': 'authorization_code', @@ -769,13 +769,13 @@ class Communication { 'code_verifier': codeVerifier, }); - const postRedeemProfileCodeConfig = Communication._axiosConfig('POST', urlObj, formData, {}, { + const postRedeemCodeConfig = Communication._axiosConfig('POST', urlObj, formData, {}, { [Enum.Header.ContentType]: Enum.ContentType.ApplicationForm, [Enum.Header.Accept]: `${Enum.ContentType.ApplicationJson}, ${Enum.ContentType.Any};q=0.1`, }); try { - const response = await this.axios(postRedeemProfileCodeConfig); + const response = await this.axios(postRedeemCodeConfig); try { return JSON.parse(response.data); } catch (e) { @@ -783,24 +783,39 @@ class Communication { throw e; } } catch (e) { - this.logger.error(_scope, 'redeem profile code request failed', { error: e, url: urlObj.href }); + this.logger.error(_scope, 'redeem code request failed', { error: e, url: urlObj.href }); return; } } /** - * Verify a token with an IdP endpoint, using the Authentication header supplied. + * Deprecated method name. + * @see redeemCode + * @param {URL} urlObj + * @param {String} code + * @param {Strin} codeVerifier + * @param {String} clientId + * @param {String} redirectURI + * @returns {Object} + */ + async redeemProfileCode(urlObj, code, codeVerifier, clientId, redirectURI) { + return await this.redeemCode(urlObj, code, codeVerifier, clientId, redirectURI); + } + + + /** + * Verify a token with an IdP endpoint, using the Authorization header supplied. * @param {URL} introspectionUrlObj - * @param {String} authenticationHeader + * @param {String} authorizationHeader * @param {String} token */ - async introspectToken(introspectionUrlObj, authenticationHeader, token) { + async introspectToken(introspectionUrlObj, authorizationHeader, token) { const _scope = _fileScope('introspectToken'); const formData = common.formData({ token }); const postIntrospectConfig = Communication._axiosConfig('POST', introspectionUrlObj, formData, {}, { - [Enum.Header.Authentication]: authenticationHeader, + [Enum.Header.Authorization]: authorizationHeader, [Enum.Header.ContentType]: Enum.ContentType.ApplicationForm, [Enum.Header.Accept]: `${Enum.ContentType.ApplicationJson}, ${Enum.ContentType.Any};q=0.1`, }); @@ -844,10 +859,10 @@ class Communication { /** * Attempt to deliver a ticket to an endpoint. * N.B. does not absorb errors - * @param {*} ticketEndpointUrlObj - * @param {*} resourceUrlObj - * @param {*} subjectUrlObj - * @param {*} ticket + * @param {URL} ticketEndpointUrlObj + * @param {URL} resourceUrlObj + * @param {URL} subjectUrlObj + * @param {String} ticket * @returns {Promise} */ async deliverTicket(ticketEndpointUrlObj, resourceUrlObj, subjectUrlObj, ticket) {