aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-03-05 16:45:10 -0800
committerAdam Soltys <[email protected]>2026-03-05 22:20:52 -0800
commit87d01366d1de2a28c81ca56d9835ef00fbf8d7d5 (patch)
tree370b323db84891aea00c208cdde9b0a529f05e23
parent4ac3f491fbb77433aef4dd8fcf560a1d1475e0bd (diff)
downloadcoinos-server-87d01366d1de2a28c81ca56d9835ef00fbf8d7d5.tar.gz
coinos-server-87d01366d1de2a28c81ca56d9835ef00fbf8d7d5.zip
auth fix
-rw-r--r--lib/ark.ts2
-rw-r--r--routes/users.ts24
2 files changed, 17 insertions, 9 deletions
diff --git a/lib/ark.ts b/lib/ark.ts
index dd35ca21..792ef142 100644
--- a/lib/ark.ts
+++ b/lib/ark.ts
@@ -120,7 +120,7 @@ export const refreshArkWallet = async (force = false) => {
failedBoardingOutpoints.clear();
break;
} catch (e: any) {
- const retriable = /not enough intent confirmations/i.test(e.message);
+ const retriable = /not enough intent confirmations|timed out|signing_session/i.test(e.message);
if (!retriable) failedBoardingOutpoints.add(outpointKey(utxo));
warn("ark onboard failed:", utxo.value, "sats:", e.message);
}
diff --git a/routes/users.ts b/routes/users.ts
index f1f6a302..8dc384af 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -24,7 +24,7 @@ import { getPublicKey, nip19, verifyEvent } from "nostr-tools";
import { hexToBytes } from "@noble/hashes/utils.js";
import { authenticator } from "otplib";
import { v4 } from "uuid";
-import { setCookie } from "hono/cookie";
+import { getCookie, setCookie } from "hono/cookie";
import { setupBip353, teardownBip353 } from "$lib/bip353";
import { PaymentType } from "$lib/types";
@@ -230,7 +230,10 @@ export default {
const user = c.get("user");
const body = await c.req.json();
try {
- const { id: tokid } = jwt.verify(c.req.header("authorization").split(" ")[1], config.jwt);
+ const authHeader = c.req.header("authorization");
+ const token = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : getCookie(c, "token");
+ if (!token) fail("unauthorized");
+ const { id: tokid } = jwt.verify(token, config.jwt);
l("updating user", user.username, tokid);
if (user.id !== tokid) fail("unauthorized");
@@ -257,13 +260,18 @@ export default {
else fail("Key in use by another account");
}
- const event = JSON.parse(body.event);
- const challenge = event.tags.find((t) => t[0] === "challenge")[1];
- const ch = await g(`challenge:${challenge}`);
- if (!ch) fail("Invalid or expired challenge");
+ // Allow initial pubkey setting without signed event (e.g. during registration)
+ if (user.pubkey && body.event) {
+ const event = JSON.parse(body.event);
+ const challenge = event.tags.find((t) => t[0] === "challenge")[1];
+ const ch = await g(`challenge:${challenge}`);
+ if (!ch) fail("Invalid or expired challenge");
- if (!verifyEvent(event) || event.pubkey !== pubkey)
- fail("Invalid signature or challenge mismatch.");
+ if (!verifyEvent(event) || event.pubkey !== pubkey)
+ fail("Invalid signature or challenge mismatch.");
+ } else if (user.pubkey) {
+ fail("Signed event required to change pubkey");
+ }
pubkey = pubkey.replace(/\s*/g, "");
if (pubkey.length !== 64) fail(`Invalid pubkey ${pubkey}`);