@spirobel/monero-wallet-api 0.6.12 → 0.6.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,17 +26,24 @@ function make(payload) {
26
26
  const base = `${TOOL_MAGIC_STRING}001_amount_${payload.amount}_address_${payload.address}`;
27
27
  return payload.no_check ? `${base}_no_check` : base;
28
28
  }
29
+ // base58, 95 chars for a standard address and 106 for an integrated one.
30
+ const MONERO_ADDRESS_SHAPE = /^[1-9A-HJ-NP-Za-km-z]{95}$|^[1-9A-HJ-NP-Za-km-z]{106}$/;
29
31
  async function validate_check(invo) {
30
32
  const tool = invo.tool;
31
33
  if (tool.tool_id !== "001")
32
34
  return "unverified";
33
35
  if (tool.payload.no_check)
34
36
  return "unverified";
37
+ // the address goes into the path. a real address is base58 and 95 or 106 chars.
38
+ // anything else could rewrite the request path, so it never reaches the fetch.
39
+ if (!MONERO_ADDRESS_SHAPE.test(tool.payload.address))
40
+ return "invalid";
35
41
  const link = invo[invo.found_in];
36
42
  const invo_link = new URL(link);
37
43
  const checkUrl = `${invo_link.origin}/monerochan001/${tool.payload.address}`;
38
44
  try {
39
- const result = (await (await fetch(checkUrl)).json());
45
+ // no redirects: a shop must not bounce the request to another host.
46
+ const result = (await (await fetch(checkUrl, { redirect: "error" })).json());
40
47
  if (result &&
41
48
  typeof result === "object" &&
42
49
  "valid_address" in result &&
@@ -17,6 +17,5 @@ declare global {
17
17
  }
18
18
  export declare function interceptToolLinkCallback(e: Event): void;
19
19
  export declare function deliverToolUrl(url: string): boolean;
20
- export declare function DefaultConfirmationCallback(loc_href: string): boolean;
21
- export declare function installToolLinkEventInterception(confirmationcallback?: (loc_href: string) => boolean): void;
20
+ export declare function installToolLinkEventInterception(): void;
22
21
  export {};
@@ -71,11 +71,8 @@ export function deliverToolUrl(url) {
71
71
  deliver(invo);
72
72
  return true;
73
73
  }
74
- export function DefaultConfirmationCallback(loc_href) {
75
- return window.confirm("Did you just follow a monerochan tool link?");
76
- }
77
- export function installToolLinkEventInterception(confirmationcallback = DefaultConfirmationCallback) {
74
+ export function installToolLinkEventInterception() {
75
+ // click only. keyboard activation (enter) dispatches a click, a touch tap does too.
76
+ // a keydown on a focused link is not an activation, so it must not deliver.
78
77
  document.addEventListener("click", interceptToolLinkCallback, true);
79
- document.addEventListener("touchend", interceptToolLinkCallback, true);
80
- document.addEventListener("keydown", interceptToolLinkCallback, true);
81
78
  }
@@ -14,6 +14,7 @@ export declare const tools: {
14
14
  };
15
15
  export type ToolId = keyof typeof tools;
16
16
  export declare const TOOL_IDS: ToolId[];
17
+ export declare const TOOL_IDS_WITHOUT_DIRECT_OPEN: ToolId[];
17
18
  export declare function getToolUiByPermissions(permissions: ToolPermission[]): ToolUiCopy | null;
18
19
  type PayloadOf<A> = A extends ToolArm<infer P, infer _E> ? P : never;
19
20
  export type MoneroTool = {
@@ -10,6 +10,9 @@ export const tools = {
10
10
  "002": tool002,
11
11
  };
12
12
  export const TOOL_IDS = Object.keys(tools);
13
+ // tool calls that cannot be started from a tool link. the content script port
14
+ // carries the rest of the exchange, so the page that made the call has to stay.
15
+ export const TOOL_IDS_WITHOUT_DIRECT_OPEN = ["002"];
13
16
  export function getToolUiByPermissions(permissions) {
14
17
  const want = new Set(permissions);
15
18
  for (const id of Object.keys(tools)) {