diff options
| author | Adam Soltys <[email protected]> | 2023-01-06 13:59:03 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-01-06 13:59:03 -0800 |
| commit | 8266d3adad8d093212b208ff93e6bee41f3370e3 (patch) | |
| tree | 3325b0c9ae32b107603d0dac1bfa2c5493f8b458 | |
| parent | b1aa064c6f19946e0aac4fb79700f848c86faa4b (diff) | |
| download | coinos-server-8266d3adad8d093212b208ff93e6bee41f3370e3.tar.gz coinos-server-8266d3adad8d093212b208ff93e6bee41f3370e3.zip | |
locktime field, uuid for token
| -rw-r--r-- | db/models/users.js | 3 | ||||
| -rw-r--r-- | lib/nostr.js | 61 | ||||
| -rw-r--r-- | lib/passport.js | 14 | ||||
| -rw-r--r-- | lib/whitelist.js | 1 | ||||
| -rw-r--r-- | routes/users.js | 31 |
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(); |
