Skip to content

Commit

Permalink
initial request queue logic
Browse files Browse the repository at this point in the history
Making progress towards:

#2369

Signed-off-by: William Casarin <[email protected]>
  • Loading branch information
jb55 committed Aug 8, 2024
1 parent fe3ec36 commit 1bbf0f8
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Damoose/Damoose.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<false/>
</dict>
</plist>
46 changes: 42 additions & 4 deletions Damoose/Resources/background.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
let damoose = {
queue: {},
reqids: 0,
}

if (request.greeting === "hello")
return Promise.resolve({ farewell: "goodbye" });
function queue_request(d, kind, host, sendResponse) {
const id = ++d.reqids
if (d.queue[host] == null)
d.queue[host] = []
d.queue[host].push({kind, id, sendResponse})
}

browser.runtime.onMessage.addListener((message, _sender, sendResponse) => {
switch (message.kind) {
// window.nostr
case 'getPubKey':
case 'signEvent':
case 'nip04.encrypt':
case 'nip04.decrypt':
case 'getRelays':
queue_request(damoose, message.kind, message.host, sendResponse);
return true;

//
// extension <-> page comms
//
// *requests*
// The auth popup asks for the latest requests that we have
// queued. This simply returns it to the tab/page in question.
//
case 'requests':
const payload = {
requests: damoose.queue[message.host] || [],
host: message.host
};
return Promise.resolve(payload)

default:
return Promise.resolve();
}
});



98 changes: 92 additions & 6 deletions Damoose/Resources/content.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,93 @@
browser.runtime.sendMessage({ greeting: "hello" }).then((response) => {
console.log("Received response: ", response);
});
let script = document.createElement('script');
script.setAttribute('src', browser.runtime.getURL('nostr.js'));
document.body.appendChild(script);
console.log("Added Damoose the nostr helper to the page.")


function test_iframe() {
const iframe = document.createElement('iframe');
// Create an iframe for the secure popup
iframe.src = browser.runtime.getURL('popup.html'); // Load the secure popup HTML
iframe.style.position = 'fixed';
iframe.style.bottom = '0'; // Align the iframe to the bottom of the screen
iframe.style.left = '0';
iframe.style.width = '100%'; // Make the iframe span the entire width of the screen
iframe.style.height = '50%'; // Make the iframe cover the bottom half of the screen
iframe.style.borderTop = '2px solid black';
iframe.style.zIndex = '10000'; // Ensure it's on top of other elements
iframe.style.display = 'none'; // Initially hidden
iframe.style.backgroundColor = 'white'; // Opaque background

// Add sandbox attributes to prevent host page access
iframe.sandbox = 'allow-scripts allow-same-origin';

// Append the iframe to the body
document.body.appendChild(iframe);

// Function to show the iframe popup
function toggle_popup() {
if (iframe.style.display === 'block')
iframe.style.display = 'none';
else
iframe.style.display = 'block';
}

// Example trigger
document.addEventListener('keydown', function(event) {
if (event.key === 'o') { // Press 'o' to show the iframe popup
toggle_popup();
}
});

window.addEventListener('message', async message => {
const validEvents = [
// window.nostr stuff
'getPubKey',
'signEvent',
'getRelays',
'nip04.encrypt',
'nip04.decrypt',

// plugin stuff
'popup_initialized',
];
let { kind, reqId, payload } = message.data;
if (!validEvents.includes(kind)) return;

if (kind === 'popup_initialized') {
// get all the queued requests for this host from the extension
const requests = await browser.runtime.sendMessage({
kind: 'requests',
host: window.location.host,
});

if (browser.runtime.lastError)
console.log(browser.runtime.lastError)

// send initial requests
iframe.contentWindow.postMessage({
kind: 'requests',
payload: requests,
}, '*')
} else {
// window.nostr stuff
const host = window.location.host
const msg = {kind, payload, host}
const result = await browser.runtime.sendMessage(msg)

iframe.contentWindow.postMessage({
kind: 'request',
payload: msg,
}, '*')

console.log(result);

kind = `return_${kind}`;

window.postMessage({ kind, reqId, payload: result }, '*');
}
});
}

test_iframe()

browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log("Received request: ", request);
});
28 changes: 23 additions & 5 deletions Damoose/Resources/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"manifest_version": 3,
"default_locale": "en",

"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"name": "Damoose",
"description": "The Damus nostr safari companion. Protect your key and create web highlights.",
"version": "1.0",

"icons": {
Expand All @@ -16,18 +16,36 @@

"background": {
"scripts": [ "background.js" ],
"type": "module"
"type": "module",
"run_at": "document_end"
},

"content_scripts": [{
"js": [ "content.js" ],
"matches": [ "*://example.com/*" ]
"matches": [ "*://*/*" ]
}],

"web_accessible_resources": [
{
"resources": [
"nostr.js",
"popup.js",
"popup.html"
],
"matches": [
"<all_urls>"
]
}
],

"content_security_policy": {
"extension_pages": "script-src 'self'"
},

"action": {
"default_popup": "popup.html",
"default_icon": "images/toolbar-icon.svg"
},

"permissions": [ ]
"permissions": [ "nativeMessaging" ]
}
70 changes: 70 additions & 0 deletions Damoose/Resources/nostr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// nostr.js
//
// Code from nostore
//


window.nostr = {
requests: {},

async getPublicKey() {
return await this.broadcast('getPubKey');
},

async signEvent(event) {
return await this.broadcast('signEvent', event);
},

async getRelays() {
return await this.broadcast('getRelays');
},

// This is here for Alby comatibility. This is not part of the NIP-07 standard.
// I have found at least one site, nostr.band, which expects it to be present.
async enable() {
return { enabled: true };
},

broadcast(kind, payload) {
let reqId = Math.random().toString();
return new Promise((resolve, _reject) => {
this.requests[reqId] = resolve;
window.postMessage({ kind, reqId, payload }, '*');
});
},

nip04: {
async encrypt(pubKey, plainText) {
return await window.nostr.broadcast('nip04.encrypt', {
pubKey,
plainText,
});
},

async decrypt(pubKey, cipherText) {
return await window.nostr.broadcast('nip04.decrypt', {
pubKey,
cipherText,
});
},
},
};


window.addEventListener('message', message => {
const validEvents = [
'getPubKey',
'signEvent',
'getRelays',
'nip04.encrypt',
'nip04.decrypt',
].map(e => `return_${e}`);
let { kind, reqId, payload } = message.data;

if (!validEvents.includes(kind)) return;

window.nostr.requests[reqId]?.(payload);
delete window.nostr.requests[reqId];
});

3 changes: 1 addition & 2 deletions Damoose/Resources/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
}

body {
width: 100px;
/* width: 100px;*/
padding: 10px;

font-family: system-ui;
text-align: center;
}

@media (prefers-color-scheme: dark) {
Expand Down
5 changes: 4 additions & 1 deletion Damoose/Resources/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
<script type="module" src="popup.js"></script>
</head>
<body>
<strong>Hello World!</strong>
<strong>THE DAMOOSE IS HERE!</strong>
<div id="requests">

</div>
</body>
</html>
41 changes: 40 additions & 1 deletion Damoose/Resources/popup.js
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
console.log("Hello World!", browser);

let requests = []

window.addEventListener('message', message => {
const { kind, reqId, payload } = message.data;
if (kind === 'requests') {
requests = requests.concat(payload.requests)
} else if (kind === 'request') {
requests.push(payload)
}

update_view(payload.host, requests)
});

function update_view(host, rs) {
const reqs = document.getElementById("requests")
const req_lis = rs.map(r => `<li>${r.kind}</li>`).join("\n")

reqs.innerHTML = `
<pre>${host}</pre> is requesting:
<ul>
${req_lis}
</ul>
`
}

// let the page know the popup iframe is ready to receive nip07 requests for
// approval/disapproval
function popup_initialized() {
window.parent.postMessage({ kind: "popup_initialized" }, '*');
}

function resolve_request(reqId, kind, payload) {
window.parent.postMessage({ kind, reqId, payload }, '*');
}

popup_initialized()



0 comments on commit 1bbf0f8

Please sign in to comment.