aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-06 13:59:03 -0800
committerAdam Soltys <[email protected]>2023-01-06 13:59:03 -0800
commit8266d3adad8d093212b208ff93e6bee41f3370e3 (patch)
tree3325b0c9ae32b107603d0dac1bfa2c5493f8b458
parentb1aa064c6f19946e0aac4fb79700f848c86faa4b (diff)
downloadcoinos-server-8266d3adad8d093212b208ff93e6bee41f3370e3.tar.gz
coinos-server-8266d3adad8d093212b208ff93e6bee41f3370e3.zip
locktime field, uuid for token
-rw-r--r--db/models/users.js3
-rw-r--r--lib/nostr.js61
-rw-r--r--lib/passport.js14
-rw-r--r--lib/whitelist.js1
-rw-r--r--routes/users.js31
5 files changed, 66 insertions, 44 deletions
diff --git a/db/models/users.js b/db/models/users.js
index cc63ac57..23dab0bf 100644
--- a/db/models/users.js
+++ b/db/models/users.js
@@ -247,6 +247,9 @@ const attributes = {
},
phone: {
type: DataTypes.STRING(255)
+ },
+ locktime: {
+ type: DataTypes.INTEGER(11)
}
};
diff --git a/lib/nostr.js b/lib/nostr.js
index 99265f7d..4730883f 100644
--- a/lib/nostr.js
+++ b/lib/nostr.js
@@ -5,22 +5,16 @@ import { broadcast } from "$lib/sockets";
import store from "$lib/store";
import redis from "$lib/redis";
import proxy from "@fastify/http-proxy";
+import { wait } from "$lib/utils";
app.register(proxy, {
upstream: config.nostr,
prefix: "/nostr",
rewritePrefix: "",
- disableRequestLogging: true,
+ disableRequestLogging: true
});
-const relays = [
- config.relay,
- "wss://relay.damus.io",
- "wss://nostr-pub.wellorder.net",
- "wss://nostr.rocks",
-];
-
-export const pool = RelayPool(relays);
+export const pool = RelayPool(config.relays);
pool.on("open", relay => {
if (relay.url.includes(config.relay)) coinos = relay;
@@ -31,38 +25,63 @@ export let coinos;
let now = () => Math.round(Date.now() / 1000);
let timeouts = {};
-export let q = async (sub, query, timeout = 8000) =>
+export let q = async (sub, query, timeout = 20000) =>
new Promise(async (r, j) => {
+ let start = Date.now();
+ let seen = [];
let rejected;
- if (!coinos) return j(new Error("relay not initialized"));
query.since = await redis.get(`since:${sub}`);
if (now() - query.since < 3600) return r();
+ let done = { [sub]: [] };
- coinos.on("eose", s => {
- return !rejected && s === sub && r(timeouts[sub].clear());
- });
+ let check = s => {
+ let elapsed = Date.now() - start;
+ if (rejected) return true;
+ if (done[s].length === pool.relays.length || elapsed > 200) {
+ r();
+ if (timeouts[s]) timeouts[s].clear();
+ return true;
+ }
+ };
timeouts[sub] = {
async clear() {
clearTimeout(this.timer);
delete timeouts[sub];
- coinos.unsubscribe(sub);
+ pool.unsubscribe(sub);
await redis.set(`since:${sub}`, now());
},
- extend(t = timeout) {
+ extend(ev) {
+ if (ev) {
+ if (seen.includes(ev.id)) return;
+ seen.push(ev.id);
+ seen.length > 1000 && seen.shift();
+ }
+
clearTimeout(this.timer);
this.timer = setTimeout(() => {
j(new Error(`query timed out: ${sub} ${Date.now()}`));
- coinos.unsubscribe(sub);
+ pool.unsubscribe(sub);
rejected = true;
- }, t);
+ }, timeout);
},
timer: undefined
};
- timeouts[sub].extend(timeout);
- coinos.subscribe(sub, query);
+ timeouts[sub].extend();
+ pool.subscribe(sub, query);
+
+ pool.on("eose", (relay, s) => {
+ if (done[s]) done[s].push(relay.url);
+ check(s);
+ });
+
+ try {
+ await wait(() => check(sub));
+ } catch (e) {
+ console.log(e);
+ }
});
let seen = [];
@@ -75,7 +94,7 @@ let getUser = async pubkey =>
};
pool.on("event", async (relay, sub, ev) => {
- if (timeouts[sub]) timeouts[sub].extend();
+ if (timeouts[sub]) timeouts[sub].extend(ev);
try {
let content;
try {
diff --git a/lib/passport.js b/lib/passport.js
index ac2949a5..1244aab5 100644
--- a/lib/passport.js
+++ b/lib/passport.js
@@ -35,13 +35,19 @@ fastifyPassport.use(
},
async (payload, next) => {
try {
- let { username } = payload;
+ let { username, uuid } = payload;
+ let where = {};
+
+ if (username)
+ where.username = { [Op.or]: [username, username.replace(/ /g, "")] };
+
+ if (uuid) where.uuid = uuid;
+
let user = await db.User.findOne({
- where: {
- username: { [Op.or]: [username, username.replace(/ /g, "")] }
- },
+ where,
include: { model: db.Account, as: "account" }
});
+
if (user.locked) throw new Error("account is locked");
next(null, user);
} catch (e) {
diff --git a/lib/whitelist.js b/lib/whitelist.js
index e78bc8e5..4e4dc14e 100644
--- a/lib/whitelist.js
+++ b/lib/whitelist.js
@@ -16,6 +16,7 @@ export default [
"id",
"index",
"keys",
+ "locktime",
"payments",
"pubkey",
"profile",
diff --git a/routes/users.js b/routes/users.js
index c935a137..764d1f03 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -4,13 +4,10 @@ import config from "$config";
import store from "$lib/store";
import { auth, optionalAuth } from "$lib/passport";
import { getUser, uniq, wait } from "$lib/utils";
-import axios from "axios";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { authenticator } from "otplib";
import Sequelize from "@sequelize/core";
-import bitcoin from "bitcoinjs-lib";
-import liquid from "liquidjs-lib";
import { fromBase58, fromPrivateKey } from "bip32";
import { Mutex } from "async-mutex";
import bip32 from "bip32";
@@ -191,7 +188,7 @@ app.post("/user", auth, async (req, res) => {
let { confirm, password, pin, newpin, username } = req.body;
if (user.pin && !(pin === user.pin)) throw new Error("Pin required");
- if (typeof newpin !== 'undefined') user.pin = newpin;
+ if (typeof newpin !== "undefined") user.pin = newpin;
if (!user.pin) user.pin = null;
let exists;
@@ -210,26 +207,22 @@ app.post("/user", auth, async (req, res) => {
if (user.username !== username)
l("changing username", user.username, username);
user.username = username;
-
- token = jwt.sign({ username }, config.jwt);
- res.cookie("token", token, {
- expires: new Date(Date.now() + 432000000)
- });
}
let attributes = [
- "unit",
+ "address",
"cipher",
+ "currencies",
+ "currency",
+ "email",
+ "fiat",
+ "locktime",
"pubkey",
"salt",
- "currency",
- "currencies",
+ "seed",
"tokens",
"twofa",
- "seed",
- "fiat",
- "email",
- "address"
+ "unit"
];
for (let a of attributes) {
@@ -356,8 +349,8 @@ let login = async (req, res) => {
try {
const url = `${callback}&sig=${sig}&key=${key}`;
- const response = await axios.get(url);
- res.send(response.data);
+ const response = await got(url).json();
+ res.send(response);
} catch (e) {
err("problem calling lnurl login", e.message);
res.code(500).send(e.message);
@@ -393,7 +386,7 @@ let login = async (req, res) => {
req.headers["x-forwarded-for"] || req.connection.remoteAddress
);
- let payload = { username: user.username };
+ let payload = { uuid: user.uuid };
let token = jwt.sign(payload, config.jwt);
res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
user.accounts = await user.getAccounts();