JSFiddle - React, Tailwind, and code Playground

by buckaroo_nl

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<div class="category-info helper pt0 content-wrapper" id="authentication-debugger">
  <div class="row">
    <div class="col-md-5">
      <div class="category-content">
        <form class="form">
          
          <label for="requestUrl">Request URL</label>
          <input id="requestUrl" value="testcheckout.buckaroo.nl/json/Transaction" />
          <label for="websiteKey">Website Key</label>
          <input id="websiteKey" value="" />
          <label for="apiKey">Secret Key</label>
          <input id="apiKey" value="" />
          <label for="nonce">Nonce</label>
          <input id="nonce" value="" />
          <label for="timeStamp">Time Stamp</label>
          <input id="timeStamp" value="" />
          
          
          <label for="postData">Post Data</label>
          <textarea id="postData" value=""></textarea>
          
          <input type="submit" value="Execute" class="button blue stroke rounded small">
        </form>
      </div>
    </div>
    <div class="col-md-7 authdebugger-output">
      <ol id="log" class="form-output"></ol>
    </div>
  </div>
</div>

SCSS

html,body {
  font-family: Open Sans, sans-serif;
  margin: 5px 0;
}

.row {
  .col-md-5 {
    width: 40%;
    float: left;
  }
  .col-md-7 {
    width: 60%;
    float: left;
  }
}

ol {
  margin: 0;
  
  li {
    margin:2px 0;
    overflow-wrap: anywhere;
  }
}

.form {
        font-size: 14px;

  
  label {
    display: block;
    width: 120px;
    float: left;
    clear: both;
    margin: 5px 0;
    line-height: 1.6;
    }

  input {
    line-height: 1.6;
    margin: 5px 0;
    display: block;
    float: left;
  }

  textarea {
    display: block;
    clear: both;
    width: 100%;
    }
}

JavaScript

$(function () {
	// set dummy values
	$("#timeStamp").val(Math.floor((new Date).getTime() / 1000));
	$("#nonce").val(BuckHmac.GetNonce());

	$(".form").on("submit", function (e) {
		e.preventDefault();
		Start();
	});
});

var Start = function () {
	var requestUri = $("#requestUrl").val();
	var websiteKey = $("#websiteKey").val();
	var apiKey = $("#apiKey").val();
	var content = $("#postData").val();
	var httpMethod = content ? "POST" : "GET";
	var nonce = $("#nonce").val();
	var timeStamp = Number($("#timeStamp").val());

	// clear log
	$("#log").html("");

	if (requestUri.lastIndexOf("http", 0) === 0) {
		Log("ERROR: requestUri must not contain the protocol");
	}

	Log("httpMethod set to '" + httpMethod + "' because post data is '" + content + "'");

	var currentTimestamp = Math.floor((new Date).getTime() / 1000);
	if (timeStamp > currentTimestamp) {
		Log("WARNING: timeStamp is larger than current timeStamp.");
	} else if (timeStamp < (currentTimestamp - 30 * 12 * 60 * 60)) {
		Log("WARNING: timeStamp is more than 1 month ago.");
	}

	Log("timeStamp is '" + new Date(timeStamp * 1000).toUTCString() + "'");
	Log("actual timeStamp is '" + new Date(currentTimestamp * 1000).toUTCString() + "'");

	var header = BuckHmac.GetAuthHeader(requestUri, websiteKey, apiKey, content, httpMethod, nonce, timeStamp);

	Log("Complete authorization header is '" + header + "'");
}

var Log = function (text) {
	$("#log").append('<li>' + text + '</li>');
}

var BuckHmac = (function () {
	var self = {};

	function getEncodedContent(content) {
		if (content) {
			var md5 = CryptoJS.MD5(content);

			Log("MD5 hash over content => " + md5);

			var base64 = CryptoJS.enc.Base64.stringify(md5);

			Log("Base64 over MD5 hash => " + base64);

			return base64;
		}

		Log("empty Post data, nothing gets hashed");

		return content;
	}

	function getHash(websiteKey, apiKey, httpMethod, nonce, timeStamp, requestUri, content) {
		var encodedContent = getEncodedContent(content);

		var rawData =...