rename redeemProfileCode to redeemCode, with deprecated alias
[squeep-indieauth-helper] / lib / communication.js
index d52d784690917d503e852309f4256650cfc4c60e..2a69e34df0fe4f150f8b2548a131ae0ca2391ddd 100644 (file)
@@ -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<PKCEData>}
    */
   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<AxiosResponse>}
    */
   async deliverTicket(ticketEndpointUrlObj, resourceUrlObj, subjectUrlObj, ticket) {