Skip to content

Commit

Permalink
feat(nostr): support permission vor signMessage #1727
Browse files Browse the repository at this point in the history
  • Loading branch information
escapedcat committed Nov 22, 2022
1 parent ce59b73 commit a108956
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 22 deletions.
22 changes: 21 additions & 1 deletion src/app/screens/Nostr/ConfirmSignMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//import Checkbox from "../../components/Form/Checkbox";
import ConfirmOrCancel from "@components/ConfirmOrCancel";
import Container from "@components/Container";
import ContentMessage from "@components/ContentMessage";
import PublisherCard from "@components/PublisherCard";
import SuccessMessage from "@components/SuccessMessage";
import Checkbox from "@components/form/Checkbox";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
Expand All @@ -27,13 +27,16 @@ function ConfirmSignMessage() {
const origin = navState.origin as OriginData;
const [loading, setLoading] = useState(false);
const [successMessage, setSuccessMessage] = useState("");
const [rememberPermission, setRememberPermission] = useState(false);

// TODO: refactor: the success message and loading will not be displayed because after the reply the prompt is closed.
// escapedcat: is this ok because we only show these in the popup usually?
async function confirm() {
try {
setLoading(true);
msg.reply({
confirm: true,
rememberPermission,
});
setSuccessMessage(tCommon("success"));
} catch (e) {
Expand Down Expand Up @@ -73,6 +76,23 @@ function ConfirmSignMessage() {
heading={t("content", { host: origin.host })}
content={event.content}
/>
<div className="flex items-center">
<Checkbox
id="remember_permission"
name="remember_permission"
checked={rememberPermission}
onChange={(event) => {
setRememberPermission(event.target.checked);
}}
/>
<label
htmlFor="remember_permission"
className="cursor-pointer ml-2 block text-sm text-gray-900 font-medium dark:text-white"
>
{/* {t("remember.label")} */}
Remember this decission
</label>
</div>
</div>
<ConfirmOrCancel
disabled={loading}
Expand Down
80 changes: 71 additions & 9 deletions src/extension/background-script/actions/nostr/signEventOrPrompt.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import utils from "~/common/lib/utils";
import { MessageSignEvent } from "~/types";
import db from "~/extension/background-script/db";
import { DbPermission, MessageSignEvent, DbAllowance } from "~/types";

import state from "../../state";
import { validateEvent } from "./helpers";
Expand All @@ -17,22 +18,83 @@ const signEventOrPrompt = async (message: MessageSignEvent) => {
};
}

console.log("message.args.event", message.args.event);

const dbPermissions = await db.permissions
.where("host")
.equalsIgnoreCase(message.origin.host)
.toArray();

const hasPermission = dbPermissions
.filter((permission) => permission.enabled)
.map(({ method }) => method)
.includes("signMessage");

try {
const response = await utils.openPrompt<{
confirm: boolean;
}>({
...message,
action: "public/nostr/confirmSignMessage",
});
if (!response.data.confirm) {
throw new Error("User rejected");
if (!hasPermission) {
const response = await utils.openPrompt<{
confirm: boolean;
rememberPermission: boolean;
}>({
...message,
action: "public/nostr/confirmSignMessage",
});

if (!response.data.confirm) {
throw new Error("User rejected");
}

const matchingAllowance = await db.allowances
.where("host")
.equalsIgnoreCase(message.origin.host)
.first();
let allowanceId = matchingAllowance?.id;

if (!allowanceId) {
console.log("mno matching allowance");

const dbAllowance: DbAllowance = {
createdAt: Date.now().toString(),
enabled: true,
host: message.origin.host,
imageURL: "", // need to get the image
lastPaymentAt: 0,
lnurlAuth: false,
name: "",
remainingBudget: 0,
tag: "",
totalBudget: 0,
};
allowanceId = await db.allowances.add(dbAllowance);
}

console.log("matching allowance!");

if (response.data.rememberPermission) {
console.log("rememberme?");

const permission: DbPermission = {
createdAt: Date.now().toString(),
allowanceId,
host: message.origin.host,
method: "signMessage",
enabled: true,
blocked: false,
};
console.log("rememberme!", permission);

await db.permissions.add(permission);
}
}

console.log("SO HAZ permissions - message: ", message);
const signedEvent = await state
.getState()
.getNostr()
.signEvent(message.args.event);

console.log("SO HAZ permissions - signedEvent: ", signedEvent);

return { data: signedEvent };
} catch (e) {
console.error("signEvent cancelled", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("add permission", () => {
},
args: {
host: stackerNews.host,
method: "listinvoices",
method: "signMessage",
enabled: true,
blocked: false,
},
Expand All @@ -61,7 +61,7 @@ describe("add permission", () => {
allowanceId: 3,
createdAt: "1487076708000",
host: "stacker.news",
method: "listinvoices",
method: "signMessage",
blocked: false,
enabled: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import db from "../../db";
import sendPayment from "../ln/sendPayment";

const sendPaymentOrPrompt = async (message: Message) => {
console.log("sendPaymentOrPrompt");

if (!("host" in message.origin)) return;

const paymentRequest = message.args.paymentRequest;
Expand Down Expand Up @@ -38,6 +40,8 @@ async function checkAllowance(host: string, amount: number) {
}

async function sendPaymentWithAllowance(message: Message) {
console.log("sendPaymentWithAllowance");

try {
const response = await sendPayment(message);
return response;
Expand Down
19 changes: 9 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ export interface MessageAccountAll extends MessageDefault {

export interface MessagePermissionAdd extends MessageDefault {
args: {
host: string;
method: string;
enabled: boolean;
blocked: boolean;
host: DbPermission["host"];
method: DbPermission["method"];
enabled: DbPermission["enabled"];
blocked: DbPermission["blocked"];
};
action: "addPermission";
}
Expand Down Expand Up @@ -497,21 +497,20 @@ export interface DbPayment {
totalFees: number;
}

export interface Payment extends Omit<DbPayment, "id"> {
id: number;
}

export interface DbPermission {
id?: number;
createdAt: string;
allowanceId: number;
host: string;
method: string;
method: "signMessage";
enabled: boolean;
blocked: boolean;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Payment extends Omit<DbPayment, "id"> {
id: number;
}

export interface PaymentResponse
extends Pick<Payment, "destination" | "preimage" | "paymentHash"> {
route: {
Expand Down

0 comments on commit a108956

Please sign in to comment.