[rs-commit] r64 - in /redwax-signtext/trunk/src/linux/chrome: ./ _locales/ _locales/en/ images/

rs-commit at redwax.eu rs-commit at redwax.eu
Sat Sep 17 17:29:07 CEST 2022


Author: minfrin at redwax.eu
Date: Sat Sep 17 17:29:06 2022
New Revision: 64

Log:
Initial skeleton of the Chrome extension.

Added:
    redwax-signtext/trunk/src/linux/chrome/
    redwax-signtext/trunk/src/linux/chrome/README.md
    redwax-signtext/trunk/src/linux/chrome/_locales/
    redwax-signtext/trunk/src/linux/chrome/_locales/en/
    redwax-signtext/trunk/src/linux/chrome/_locales/en/messages.json
    redwax-signtext/trunk/src/linux/chrome/background.js
    redwax-signtext/trunk/src/linux/chrome/content.js
    redwax-signtext/trunk/src/linux/chrome/images/
    redwax-signtext/trunk/src/linux/chrome/images/icon-128.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/icon-256.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/icon-48.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/icon-512.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/icon-64.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/icon-96.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-16.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-19.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-32.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-38.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-48.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-72.png   (with props)
    redwax-signtext/trunk/src/linux/chrome/manifest.json
    redwax-signtext/trunk/src/linux/chrome/page.js

Added: redwax-signtext/trunk/src/linux/chrome/README.md
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/README.md	(added)
+++ redwax-signtext/trunk/src/linux/chrome/README.md	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,4 @@
+# Chrome extension
+
+This provides a manifest v3 extension for Chrome.
+

Added: redwax-signtext/trunk/src/linux/chrome/_locales/en/messages.json
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/_locales/en/messages.json	(added)
+++ redwax-signtext/trunk/src/linux/chrome/_locales/en/messages.json	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,10 @@
+{
+    "extension_name": {
+        "message": "Redwax SignText Extension",
+        "description": "The display name for the extension."
+    },
+    "extension_description": {
+        "message": "This is Redwax SignText Extension. You should tell us what your extension does here.",
+        "description": "Description of what the extension does."
+    }
+}

Added: redwax-signtext/trunk/src/linux/chrome/background.js
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/background.js	(added)
+++ redwax-signtext/trunk/src/linux/chrome/background.js	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,132 @@
+
+console.log('Redwax SignText: background started');
+
+var csPorts = [];
+var nativePort = undefined;
+
+function nativeMessaged(m) {
+
+    console.log('Redwax SignText: background: message received from native: ', m);
+
+    /*
+     * Native message response is handled here. Send the message
+     * to the correctly numbered content script.
+     */
+    csPorts.forEach(p => {
+        if (p.sender.tab.id == m.id) {
+
+           console.log('Redwax SignText: background: message passed from native to content: ', m);
+
+            p.postMessage({ uuid: m.uuid, response: m.response, contentType: m.contentType });
+        }
+    });
+}
+
+function nativeDisconnected(p) {
+
+            nativePort.onMessage.removeListener(nativeMessaged);
+            nativePort.onDisconnect.removeListener(nativeDisconnected);
+
+//    nativePort.disconnect();
+    nativePort = undefined;
+
+    csPorts.forEach(cp => {
+        cp.postMessage({ error: 'error:nativeDisconnected', exception: p.error.message });
+    });
+    console.log('Redwax SignText: native port disconnected.');
+}
+
+function connected(p) {
+    csPorts[p.sender.tab.id] = p;
+    console.log('Redwax SignText: background: connection received from content: ', p);
+    messageHandler = function(m) {
+
+        console.log('Redwax SignText: background: message received from content: ', m);
+
+        if (typeof nativePort === 'undefined') {
+
+            console.log('Redwax SignText: background: open native port (attempt one)');
+
+            nativePort = chrome.runtime.connectNative('eu.redwax.Redwax.SignText');
+            nativePort.onMessage.addListener(nativeMessaged);
+            nativePort.onDisconnect.addListener(nativeDisconnected);
+        }
+
+        let url = p.sender.tab.url ? p.sender.tab.url : p.sender.url ? p.sender.url : "No URL";
+
+        console.log('Redwax SignText: background: nativeport created');
+
+        try {
+            /*
+             * Let's try send the message on the assumption the port is
+             * open and works. On failure, try to open the port and retry.
+             */
+
+            console.log('Redwax SignText: background: send message (attempt one)');
+
+            nativePort.postMessage({ url: url, id: p.sender.tab.id, uuid: m.uuid, request: m.request, contentType: m.contentType });
+        }
+        catch (exception) {
+
+            console.log('Redwax SignText: background: open native port (attempt two)');
+
+            /*
+             * Not able to send the message. (Re)open the port and try
+             * once more.
+             */
+            nativePort = chrome.runtime.connectNative('eu.redwax.Redwax.SignText');
+            nativePort.onMessage.addListener(nativeMessaged);
+            nativePort.onDisconnect.addListener(nativeDisconnected);
+            
+            /*
+             * One more try to send the message.
+             */
+            try {
+                console.log('Redwax SignText: background: send message (attempt two)');
+                nativePort.postMessage({ url: url, id: p.sender.tab.id, uuid: m.uuid, request: m.request, contentType: m.contentType });
+            }
+            catch (exception) {
+
+                nativePort = undefined;
+
+                /*
+                 * No luck, send a message back to the content script with
+                 * the bad news.
+                 */
+                console.log('Redwax SignText: postNativeMessageFailed: ', exception);
+                p.postMessage({ uuid: m.uuid, error: 'error:postNativeMessageFailed', exception: exception.message });
+                
+            }
+            
+        }
+        
+    };
+
+    p.onMessage.addListener(messageHandler);
+
+    p.onDisconnect.addListener(function(p) {
+        p.onMessage.removeListener(messageHandler);
+        console.log('Redwax SignText: tab ' + p.sender.tab.id + ' disconnected.');
+        delete csPorts[p.sender.tab.id];
+    });
+}
+
+chrome.runtime.onConnect.addListener(connected);
+
+chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
+
+  try {
+    chrome.scripting.executeScript({
+      target: { tabId: tab.id },
+      files: ['page.js'],
+      world: "MAIN"
+    });
+  }
+  catch (error) {
+    /* some URLs cannot have scripts injected, ignore them */
+  }
+
+});
+
+console.log('Redwax SignText: background ended');
+

Added: redwax-signtext/trunk/src/linux/chrome/content.js
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/content.js	(added)
+++ redwax-signtext/trunk/src/linux/chrome/content.js	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,149 @@
+/*
+ * Handle all background script events, passing them as
+ * appropriate to the webpage.
+ */
+const port = chrome.runtime.connect(null, {
+	name: window.location.href
+});
+
+
+
+
+
+/*
+ * Chrome / Safari
+ * ===============
+ *
+ * We cannot exportFunction on Chrome or Safari. Instead, pass messages using document.dispatchEvent
+ * to get data back and forth.
+ */
+
+port.onMessage.addListener((message) => {
+	document.dispatchEvent(new CustomEvent('eu.redwax.signTextResponse', {
+		bubbles: true,
+		detail: message
+	}));
+});
+
+port.onDisconnect.addListener((p) => {
+	if (p.error) {
+		console.log(`Redwax SignText: disconnected due to an error: ${p.error.message}`);
+	} else {
+		console.log(`Redwax SignText: disconnected`);
+	}
+});
+
+
+/*
+ * Handle all webpage signtext info events, return our version
+ * information.
+ */
+document.addEventListener('eu.redwax.signTextRequestInfo', function(e) {
+	/*
+	 * We've been asked for info about the signtext extension.
+	 *
+	 * This can be used to detect support for the extension
+	 * before trying to use it.
+	 */
+	try {
+		const manifest = chrome.runtime.getManifest();
+		e.target.dispatchEvent(new CustomEvent('eu.redwax.signTextResponseInfo', {
+			bubbles: true,
+			detail: {
+				name: manifest.name,
+				version: manifest.version
+			}
+		}));
+	}
+	catch (error) {
+		/* if we've been unloaded, we fail here and do nothing */
+	}
+});
+
+/*
+ * Handle all webpage signtext events, passing them as approriate
+ * to the background script.
+ */
+document.addEventListener('eu.redwax.signTextRequest', function(e) {
+	/*
+	 * We've been asked to sign a specific request. Check the
+	 * request, and pass the request to the background if the
+	 * check passes.
+	 */
+	if (e.detail.request) {
+
+		/*
+		 * UUID valid? If not, complain.
+		 */
+		if (typeof e.detail.uuid !== 'string') {
+			/* error - uuid is missing or invalid */
+			e.target.dispatchEvent(new CustomEvent('eu.redwax.signTextResponse', {
+				bubbles: true,
+				detail: {
+					uuid: e.detail.uuid,
+					error: 'error:uuidInvalid'
+				}
+			}));
+		}
+
+		/*
+		 * Hostname valid? If not, complain.
+		 */
+		if (typeof e.detail.hostname !== 'string') {
+			/* error - hostname is missing or invalid */
+			e.target.dispatchEvent(new CustomEvent('eu.redwax.signTextResponse', {
+				bubbles: true,
+				detail: {
+					uuid: e.detail.uuid,
+					error: 'error:hostnameInvalid'
+				}
+			}));
+		}
+
+		/*
+		 * Content Type valid? If not, complain.
+		 */
+		switch (e.detail.contentType) {
+			case undefined:
+			case 'text/plain':
+			case 'application/pkcs7-mime': {
+
+				/*
+				 * Checks have passed, send message to background script.
+				 */
+				try {
+					port.postMessage({
+						uuid: e.detail.uuid,
+						hostname: location.hostname,
+						protocol: location.protocol,
+						request: e.detail.request,
+						contentType: e.detail.contentType
+					});
+				} catch (exception) {
+					e.target.dispatchEvent(new CustomEvent('eu.redwax.signTextResponse', {
+						bubbles: true,
+						detail: {
+							uuid: e.detail.uuid,
+							error: 'error:postMessageFailed',
+							exception: exception
+						}
+					}));
+				}
+
+				break;
+			}
+			default: {
+				/* error - mime type unrecognised */
+				e.target.dispatchEvent(new CustomEvent('eu.redwax.signTextResponse', {
+					bubbles: true,
+					detail: {
+						uuid: e.detail.uuid,
+						error: 'error:contentTypeUnrecognised'
+					}
+				}));
+			}
+		}
+
+	}
+});
+

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-128.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-128.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-256.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-256.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-48.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-48.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-512.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-512.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-64.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-64.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/icon-96.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/icon-96.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-16.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-16.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-19.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-19.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-32.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-32.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-38.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-38.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-48.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-48.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-72.png
==============================================================================
Binary file - no diff available.

Propchange: redwax-signtext/trunk/src/linux/chrome/images/toolbar-icon-72.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: redwax-signtext/trunk/src/linux/chrome/manifest.json
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/manifest.json	(added)
+++ redwax-signtext/trunk/src/linux/chrome/manifest.json	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,37 @@
+{
+    "manifest_version": 3,
+    "default_locale": "en",
+
+    "name": "__MSG_extension_name__",
+    "description": "__MSG_extension_description__",
+    "version": "0.9",
+
+    "icons": {
+        "48": "images/icon-48.png",
+        "96": "images/icon-96.png",
+        "128": "images/icon-128.png",
+        "256": "images/icon-256.png",
+        "512": "images/icon-512.png"
+    },
+
+    "background": {
+        "service_worker": "background.js"
+    },
+
+    "content_scripts": [
+      {
+        "matches": ["<all_urls>"],
+        "js": ["content.js"],
+        "all_frames": true,
+        "run_at": "document_start"
+      }
+    ],
+
+    "permissions": ["nativeMessaging", "scripting", "tabs"],
+
+    "host_permissions": [
+      "https://*/*",
+      "http://localhost/*"
+    ]
+
+}

Added: redwax-signtext/trunk/src/linux/chrome/page.js
==============================================================================
--- redwax-signtext/trunk/src/linux/chrome/page.js	(added)
+++ redwax-signtext/trunk/src/linux/chrome/page.js	Sat Sep 17 17:29:06 2022
@@ -0,0 +1,148 @@
+
+if (typeof window.crypto.signText === 'undefined') {
+
+    document.addEventListener('eu.redwax.signTextResponseInfo', function() {
+
+        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)
+            );
+        }
+
+        window.crypto.signText = async function SignText(source, options, ...CAs) {
+
+            const uuid = uuidv4();
+
+            /* 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 result = [];
+
+                var stringResolve;
+                var stringReject;
+
+                var promise = new Promise(
+                    function(resolve, reject) {
+                        stringResolve = resolve;
+                        stringReject = reject;
+                    }
+                );
+
+                const signTextHandler = function(e) {
+                    /* message not for us */
+                    if (!(e.uuid === undefined) && !(e.uuid === uuid)) {
+                        /* do nothing */
+                    }
+                    /* an error was received, cancel the stream */
+                    else if (e.error) {
+                        const error = new Error(e.error);
+                        stringReject(error);
+                        document.removeEventListener('eu.redwax.signTextResponse', signTextHandler);
+                    }
+                    /* an ack was received, send the next chunk */
+                    else if (e.response === true) {
+                        document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', {
+                            bubbles: true,
+                            detail: {
+                                protocol: location.protocol,
+                                hostname: location.hostname,
+                                uuid: uuid,
+                                request: {
+                                    signText: options,
+                                    CAs: CAs
+                                }
+                            }
+                        }));
+                    }
+                    /* an eos was received, we're done */
+                    else if (e.response === false) {
+                        stringResolve(result.join(""));
+                        document.removeEventListener('eu.redwax.signTextResponse', signTextHandler);
+                    }
+                    /* a response was received, send ack */
+                    else {
+                        result.push(e.response);
+                        document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', {
+                            bubbles: true,
+                            detail: {
+                                protocol: location.protocol,
+                                hostname: location.hostname,
+                                uuid: uuid,
+                                request: true
+                            }
+                        }));
+                    }
+                };
+
+                /* add our listener */
+                document.addEventListener('eu.redwax.signTextResponse', signTextHandler);
+
+                /* fire off our initial message */
+                document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequest', {
+                    bubbles: true,
+                    detail: {
+                        protocol: location.protocol,
+                        hostname: location.hostname,
+                        contentType: 'text/plain',
+                        uuid: uuid,
+                        request: source
+                    }
+                }));
+
+                return promise;
+
+            }
+            else {
+
+                const response = new Error('error:unknownType');
+
+                return response;
+            }
+
+alert("Hello there");
+
+        }
+
+    }, {
+        once: true
+    });
+
+    document.dispatchEvent(new CustomEvent('eu.redwax.signTextRequestInfo', {
+        bubbles: true
+    }));
+
+}
+



More information about the rs-commit mailing list