[rs-commit] r9 - in /redwax-signtext/trunk/src: ./ common/ common/signtext.js

rs-commit at redwax.eu rs-commit at redwax.eu
Sun Sep 19 12:02:58 CEST 2021


Author: minfrin at redwax.eu
Date: Sun Sep 19 12:02:57 2021
New Revision: 9

Log:
Initial add of the signtext wrapper.

Added:
    redwax-signtext/trunk/src/
    redwax-signtext/trunk/src/common/
    redwax-signtext/trunk/src/common/signtext.js

Added: redwax-signtext/trunk/src/common/signtext.js
==============================================================================
--- redwax-signtext/trunk/src/common/signtext.js	(added)
+++ redwax-signtext/trunk/src/common/signtext.js	Sun Sep 19 12:02:57 2021
@@ -0,0 +1,131 @@
+
+function stringReader(str) {
+  var offset = 0;
+  const chunkSize = 1024;
+  return new ReadableStream({
+    pull(controller) {
+      var nextOffset = offset+chunkSize;
+      if (nextOffset >= str.length) {
+        nextOffset = str.length;
+        controller.enqueue(str.substring(offset, nextOffset));
+        controller.close();
+      }
+      else {
+        controller.enqueue(str.substring(offset, nextOffset));
+      }
+      offset = nextOffset;
+    }
+  });
+}
+
+
+function uuidv4() {
+  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
+    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
+  );
+}
+
+function signTextReader(requestStream, options, ...CAs) {
+  const uuid = uuidv4();
+  const reader = requestStream.getReader();
+  return new ReadableStream({
+    start(controller) {
+
+      function push() {
+        reader.read().then(({ done, value }) => {
+          if (!done) {
+            document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', { bubbles: true, detail: { contentType: 'text/plain', uuid: uuid, request: value } }));
+          }
+          else {
+            document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', { bubbles: true, detail: { uuid: uuid, request: { signText: options, CAs: CAs } } }));
+          }
+        });
+      }
+
+      const signTextHandler = function (e) {
+        if (e.detail.uuid === uuid) {
+          /* an error was received, cancel the stream */
+          if (e.detail.error) {
+            controller.cancel(e.detail.error);
+            document.removeEventListener('eu.redwax.signTextResponse', signTextHandler);
+          }
+          /* an ack was received, send the next chunk */
+          else if (e.detail.response === true) {
+            push();
+          }
+          /* an eos was received, we're done */
+          else if (e.detail.response === false) {
+            controller.close();
+            document.removeEventListener('eu.redwax.signTextResponse', signTextHandler);
+          }
+          /* a response was received, enqueue the response */
+          else {
+            controller.enqueue(e.detail.response);
+            document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', { bubbles: true, detail: { uuid: uuid, request: true } }));
+          }
+        }
+      };
+
+      /* add our listener */
+      document.addEventListener('eu.redwax.signTextResponse', signTextHandler);
+
+      /* fire off initial request */
+      push();
+
+    }
+  });
+}
+
+async function readerStreamToString(stream) {
+  const reader = stream.getReader();
+  let result = '';
+  return reader.read().then(function processText({ done, value }) {
+    if (done) {
+      console.log("Stream complete:" + result);
+      return result;
+    }
+    result += value;
+    return reader.read().then(processText);
+  });
+}
+
+window.crypto.signText = async function SignText(source, options, ...CAs) {
+
+    var requestStream;
+
+    /* source is undefined, return the info */
+    if (typeof source === 'undefined') {
+        return new Promise(resolve => {
+            document.addEventListener('eu.redwax.signTextResponseInfo', resolve, {once:true});
+            document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequestInfo', { bubbles: true }));
+        }).then( e => { return e.detail; });
+    }
+
+    /* pass a string, we return a string */
+    if (typeof source === 'string') {
+        var requestStream = stringReader(source);
+    }
+
+    /* consume a ReadableStream */
+    else if (source instanceof ReadableStream) {
+        var requestStream = source;
+    }
+
+    else {
+        return Promise.reject(new Error('error:unknownType'));
+    }
+
+    const responseStream = new signTextReader(requestStream, options, CAs);
+
+    /* pass a string, we return a string */
+    if (typeof source === 'string') {
+      return readerStreamToString(responseStream);
+    }
+
+    /* return a ReadableStream */
+    else {
+        return responseStream;
+    }
+
+}
+



More information about the rs-commit mailing list