initial commit
[squeep-mystery-box] / lib / common.js
diff --git a/lib/common.js b/lib/common.js
new file mode 100644 (file)
index 0000000..fb3ec97
--- /dev/null
@@ -0,0 +1,68 @@
+'use strict';
+
+const path = require('path');
+const { randomBytes } = require('crypto');
+const { promisify } = require('util');
+const randomBytesAsync = promisify(randomBytes);
+
+
+/**
+ * Return a function which combines a part of the filename with a scope, for use in logging.
+ * @param {string} filename
+ */
+const fileScope = (filename) => {
+  let fScope = path.basename(filename, '.js');
+  if (fScope === 'index') {
+    fScope = path.basename(path.dirname(filename));
+  }
+  return (scope) => `${fScope}:${scope}`;
+}
+
+
+/**
+ * Convert Base64 to Base64URL.
+ * @param {String} input
+ * @returns {String}
+ */
+const base64ToBase64URL = (input) => {
+  return input
+    .replace(/=/g, '')
+    .replace(/\+/g, '-')
+    .replace(/\//g, '_');
+};
+
+
+/**
+ * Convert Base64URL to normal Base64.
+ * @param {String} input
+ * @returns {String}
+ */
+const base64URLToBase64 = (input) => {
+  return base64RePad(input)
+    .replace(/-/g, '+')
+    .replace(/_/, '/');
+};
+
+
+/**
+ * Add any missing trailing padding which may have been removed from Base64URL encoding.
+ * @param {String} input
+ */
+const base64RePad = (input) => {
+  const blockSize = 4;
+  const lastBlockSize = input.length % blockSize;
+  if (lastBlockSize) {
+    const missing = blockSize - lastBlockSize;
+    return input + '='.repeat(missing);
+  }
+  return input;
+};
+
+
+module.exports = {
+  base64ToBase64URL,
+  base64URLToBase64,
+  base64RePad,
+  fileScope,
+  randomBytesAsync,
+};
\ No newline at end of file