JSFiddle - React, Tailwind, and code Playground

by joshAtDoorDash

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<h2>DoorDash Merchant Values</h2>

  <i>Values provided on <a href="https://developer.doordash.com/portal/integration/drive/credentials">DoorDash API Credentials</a> page.</i>
  <br /> <br />

  <table>
    <tr>
      <td><label>Developer ID</label></td>
      <td><input type="text" id="developerId" size="40"></td>
    </tr>
    <tr>
      <td><label>Key ID</label></td>
      <td><input type="text" id="keyId" size="40"></td>
    </tr>
    <tr>
      <td><label>Signing Secret</label></td>
      <td>
        <input type="password" id="signingSecret" size="50">
      </td>
    </tr>
        <tr>
      <td>&nbsp;</td>
      <td>
        <button onclick="updateJWT()">Update JWT</button>
      </td>
    </tr>
  </table>

  <h2>JWT Parts</h2>
  <p>
    JWTs (JSON Web Tokens) consist of three parts which include the Header, Payload, and Signature. The following displays each of the these parts. 
  </p>
  <table>
    <tr>
      <td style="overflow:hidden; width:50px;">
        <label>Header</label><br />
      </td>
      <td><textarea id="jwtHeader" cols="50" rows="5" readonly></textarea>
      </td>
      <td>
        <i>dd-ver key identifies the DoorDash JWT version</i>
      </td>
    </tr>
    <tr>
      <td><label>Payload</label></td>
      <td><textarea id="jwtPayload" cols="50" rows="7" readonly></textarea>
      </td>
      <td>
      </td>
    </tr>
    <tr>
      <td><label>Signature</label></td>
      <td><textarea id="jwtSigningSecret" cols="50" rows="5" readonly>
                </textarea></td>
      <td>
        <code>HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), Signing Secret)</code>
      </td>
    </tr>
  </table>


  <h2>JWT</h2>
  
  <p>
    The JWT output is three Base64-URL strings separated by dots.
  </p>
  
  <textarea id="jwt" cols="80" rows="10"></textarea>
  
  <h2>More About DoorDash Credentails</h2>
  <ul>
    <li><a...

JavaScript

const jwtHeaderTemplate = '{"alg": "HS256","typ": "JWT","dd-ver": "DD-JWT-V1"}';
        const jwtPayloadTemplate = '{"aud": "doordash","iss": "DEVELOPER_ID","kid": "KEY_ID","iat": "ISSUE_AT","exp": "EXPIRATION"}';

        window.onload = setDefaults();

        function setDefaults() {
          document.getElementById('jwtHeader').value = JSON.stringify(JSON.parse(jwtHeaderTemplate), null, 2);
          document.getElementById('jwtPayload').value = JSON.stringify(JSON.parse(jwtPayloadTemplate), null, 2);
        }

        function base64UrlEncodeString(rawString) {
            var noSpaces = rawString.replace(/\s+/g, ''); //remove all whitespace characters
          var wordArray = CryptoJS.enc.Utf8.parse(noSpaces);

          return base64UrlEncodeWordArray(wordArray);
        }

        function base64UrlEncodeWordArray(wordArray) {
          // Return Base64Encoded String, in Base64URL format: 
          //   * all equal characters (padding) removed
          //   * all pluses replaced with dashes
          //   * all slashes replaced with underscores
          return CryptoJS.enc.Base64.stringify(wordArray)
          																	.replace(/=+$/, '')
                                            .replace(/\+/g, '-')
                                            .replace(/\//g, '_'); 
        }

        function base64UrlDecode(source) {
        	// Remove characters that were swapped when Base64URL encoded:
					//   * all dashses replaced with pluses
          //   * all underscores replaced with slashes
        	var urlDecoded = source.replace(/-/g, '+')
          											 .replace(/_/g, '/');
          
          // return parsed string as WordArray
          return CryptoJS.enc.Base64.parse(urlDecoded);
        }

        function updateJWT() {
          // TODO: Validate the 3 user provided fields are valid
          var jwtHeaderEncoded = base64UrlEncodeString(jwtHeaderTemplate); // Base64 encode the Header JSON
          var developerId =...