Skip to content

Commit

Permalink
Merge pull request #2218 from getAlby/fix/race-condition
Browse files Browse the repository at this point in the history
fix: race conditions
  • Loading branch information
bumi authored May 2, 2023
2 parents f891aaa + 6c8e69b commit 475221e
Show file tree
Hide file tree
Showing 15 changed files with 187 additions and 215 deletions.
2 changes: 1 addition & 1 deletion src/app/screens/Nostr/ConfirmSignMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ScreenHeader from "~/app/components/ScreenHeader";
import { useNavigationState } from "~/app/hooks/useNavigationState";
import { USER_REJECTED_ERROR } from "~/common/constants";
import msg from "~/common/lib/msg";
import { Event } from "~/extension/ln/nostr/types";
import { Event } from "~/extension/providers/nostr/types";
import type { OriginData } from "~/types";

function ConfirmSignMessage() {
Expand Down
2 changes: 1 addition & 1 deletion src/extension/background-script/actions/nostr/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Hex from "crypto-js/enc-hex";
import sha256 from "crypto-js/sha256";
import db from "~/extension/background-script/db";
import state from "~/extension/background-script/state";
import { Event } from "~/extension/ln/nostr/types";
import { Event } from "~/extension/providers/nostr/types";

export async function hasPermissionFor(method: string, host: string) {
if (!host) {
Expand Down
2 changes: 1 addition & 1 deletion src/extension/background-script/nostr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { AES } from "crypto-js";
import Base64 from "crypto-js/enc-base64";
import Hex from "crypto-js/enc-hex";
import Utf8 from "crypto-js/enc-utf8";
import { Event } from "~/extension/ln/nostr/types";
import { Event } from "~/extension/providers/nostr/types";

import { getEventHash, signEvent } from "../actions/nostr/helpers";

Expand Down
33 changes: 19 additions & 14 deletions src/extension/content-script/onend.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ async function init() {
if (ev.data && !ev.data.response) {
// if an enable call railed we ignore the request to prevent spamming the user with prompts
if (isRejected) {
console.error(
"Enable had failed. Rejecting further WebLN calls until the next reload"
);
postMessage(ev, {
error:
"webln.enable() failed (rejecting further window.webln calls until the next reload)",
});
return;
}
// if a call is active we ignore the request
if (callActive) {
console.error("WebLN call already executing");
postMessage(ev, { error: "window.webln call already executing" });
return;
}
// limit the calls that can be made from webln
Expand Down Expand Up @@ -96,16 +97,7 @@ async function init() {
isRejected = true;
}
}
window.postMessage(
{
application: "LBE",
response: true,
data: response,
//action: ev.data.action,
scope: "webln",
},
"*" // TODO use origin
);
postMessage(ev, response);
};
callActive = true;
return browser.runtime
Expand All @@ -118,4 +110,17 @@ async function init() {

init();

function postMessage(ev, response) {
window.postMessage(
{
id: ev.data.id,
application: "LBE",
response: true,
data: response,
scope: "webln",
},
"*"
);
}

export {};
35 changes: 21 additions & 14 deletions src/extension/content-script/onendnostr.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async function init() {
return;
}

// message listener to listen to inpage webln calls
// message listener to listen to inpage nostr calls
// those calls get passed on to the background script
// (the inpage script can not do that directly, but only the inpage script can make webln available to the page)
window.addEventListener("message", (ev) => {
Expand All @@ -43,14 +43,16 @@ async function init() {
if (ev.data && !ev.data.response) {
// if an enable call railed we ignore the request to prevent spamming the user with prompts
if (isRejected) {
console.error(
"Enable had failed. Rejecting further WebLN calls until the next reload"
);
postMessage(ev, {
error:
"window.nostr call cancelled (rejecting further window.nostr calls until the next reload)",
});
return;
}

// if a call is active we ignore the request
if (callActive) {
console.error("nostr call already executing");
postMessage(ev, { error: "window.nostr call already executing" });
return;
}

Expand Down Expand Up @@ -86,15 +88,7 @@ async function init() {
}
}

window.postMessage(
{
application: "LBE",
response: true,
data: response,
scope: "nostr",
},
"*" // TODO use origin
);
postMessage(ev, response);
};

callActive = true;
Expand All @@ -106,6 +100,19 @@ async function init() {
});
}

function postMessage(ev, response) {
window.postMessage(
{
id: ev.data.id,
application: "LBE",
response: true,
data: response,
scope: "nostr",
},
"*"
);
}

init();

export {};
2 changes: 1 addition & 1 deletion src/extension/inpage-script/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ABORT_PROMPT_ERROR, USER_REJECTED_ERROR } from "~/common/constants";

import WebLNProvider from "../ln/webln";
import WebLNProvider from "../providers/webln";

if (document) {
// window.webln is normally loaded onstart (see onstart.js)
Expand Down
2 changes: 1 addition & 1 deletion src/extension/inpage-script/nostr.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import NostrProvider from "../ln/nostr";
import NostrProvider from "../providers/nostr";

if (document) {
window.nostr = new NostrProvider();
Expand Down
4 changes: 2 additions & 2 deletions src/extension/inpage-script/webln.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import WebBTCProvider from "../ln/webbtc";
import WebLNProvider from "../ln/webln";
import WebBTCProvider from "../providers/webbtc";
import WebLNProvider from "../providers/webln";

if (document) {
window.webln = new WebLNProvider();
Expand Down
102 changes: 0 additions & 102 deletions src/extension/ln/nostr/index.ts

This file was deleted.

70 changes: 70 additions & 0 deletions src/extension/providers/nostr/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { postMessage } from "../postMessage";
import { Event } from "./types";

declare global {
interface Window {
nostr: NostrProvider;
}
}

export default class NostrProvider {
nip04 = new Nip04(this);
enabled: boolean;

constructor() {
this.enabled = false;
}

async enable() {
if (this.enabled) {
return { enabled: true };
}
return await this.execute("enable");
}

async getPublicKey() {
await this.enable();
return await this.execute("getPublicKeyOrPrompt");
}

async signEvent(event: Event) {
await this.enable();
return this.execute("signEventOrPrompt", { event });
}

async signSchnorr(sigHash: string) {
await this.enable();
return this.execute("signSchnorrOrPrompt", { sigHash });
}

async getRelays() {
await this.enable();
return this.execute("getRelays");
}

// NOTE: new call `action`s must be specified also in the content script
execute(
action: string,
args?: Record<string, unknown>
): Promise<Record<string, unknown>> {
return postMessage("nostr", action, args);
}
}

class Nip04 {
provider: NostrProvider;

constructor(provider: NostrProvider) {
this.provider = provider;
}

async encrypt(peer: string, plaintext: string) {
await this.provider.enable();
return this.provider.execute("encryptOrPrompt", { peer, plaintext });
}

async decrypt(peer: string, ciphertext: string) {
await this.provider.enable();
return this.provider.execute("decryptOrPrompt", { peer, ciphertext });
}
}
File renamed without changes.
51 changes: 51 additions & 0 deletions src/extension/providers/postMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export function postMessage<T>(
scope: string,
action: string,
args: T | undefined
): Promise<T> {
return new Promise((resolve, reject) => {
const id = Math.random().toString().slice(4);

// post the request to the content script. from there it gets passed to the background script and back
// in page script can not directly connect to the background script
window.postMessage(
{
id: id,
application: "LBE",
prompt: true,
action: `${scope}/${action}`,
scope: scope,
args,
},
"*" // TODO use origin
);

function handleWindowMessage(messageEvent: MessageEvent) {
// check if it is a relevant message
// there are some other events happening
if (
!messageEvent.data ||
!messageEvent.data.response ||
messageEvent.data.application !== "LBE" ||
messageEvent.data.scope !== scope ||
messageEvent.data.id !== id
) {
return;
}

if (messageEvent.data.data.error) {
reject(new Error(messageEvent.data.data.error));
} else {
// 1. data: the message data
// 2. data: the data passed as data to the message
// 3. data: the actual response data
resolve(messageEvent.data.data.data);
}

// For some reason must happen only at the end of this function
window.removeEventListener("message", handleWindowMessage);
}

window.addEventListener("message", handleWindowMessage);
});
}
Loading

0 comments on commit 475221e

Please sign in to comment.