diff options
| author | Adam Soltys <[email protected]> | 2023-01-11 22:09:48 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2023-01-12 15:44:13 -0800 |
| commit | c3565838644123e77881ff4f8536792f074047b9 (patch) | |
| tree | 96da43fd19940d2f0836e43a511f0a1fb365044d /routes | |
| parent | ded2c69ce89438326523a512b570be6eee4b23f0 (diff) | |
| download | coinos-server-c3565838644123e77881ff4f8536792f074047b9.tar.gz coinos-server-c3565838644123e77881ff4f8536792f074047b9.zip | |
migrating to redis
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/invoices.js | 188 | ||||
| -rw-r--r-- | routes/lightning/channel.js | 29 | ||||
| -rw-r--r-- | routes/lightning/channelRequest.js | 24 | ||||
| -rw-r--r-- | routes/lightning/index.js | 2 | ||||
| -rw-r--r-- | routes/requests.js | 130 | ||||
| -rw-r--r-- | routes/users.js | 68 |
6 files changed, 78 insertions, 363 deletions
diff --git a/routes/invoices.js b/routes/invoices.js index f3c95a21..ddd840ec 100644 --- a/routes/invoices.js +++ b/routes/invoices.js @@ -4,64 +4,25 @@ import { optionalAuth } from "$lib/passport"; import { err, l } from "$lib/logging"; import { SATS, derivePayRequest } from "$lib/utils"; import { emit } from "$lib/sockets"; +import { v4 } from "uuid"; +import { rd, g, s } from "$lib/redis"; -app.get("/invoice", async (req, res, next) => { - try { - const invoice = await db.Invoice.findOne({ - where: { - uuid: req.query.uuid - }, - include: [ - { - model: db.User, - as: "user", - attributes: ["username", "currency", "profile", "uuid"] - }, - { - model: db.Request, - as: "request" - } - ] - }); - - res.send(invoice); - } catch (e) { - err("invoice not found", e); - res.code(500).send("Invoice not found"); - } -}); - -app.get("/invoice/:text", async (req, res, next) => { - try { - let { text } = req.params; - let where = - text.split("-").length > 4 - ? { uuid: text } - : text.startsWith("ln") - ? { text } - : { - [Op.or]: [{ unconfidential: text }, { address: text }] - }; - - const invoice = await db.Invoice.findOne({ - where, - include: { - model: db.User, - as: "user", - attributes: ["username", "currency", "profile", "uuid"] - } - }); - - res.send(invoice); - } catch (e) { - err("invoice not found", e); - res.code(500).send("Invoice not found"); - } +app.get("/invoice", async ({ query: { id } }, res) => { + let invoice = await g(`invoice:${id}`); + invoice.user = await g(`user:${invoice.user_id}`); + res.send(invoice); }); -app.post("/invoice", optionalAuth, async (req, res, next) => { - try { - let { type = "bech32", liquidAddress, id, invoice, user, tx } = req.body; +app.post( + "/invoice", + optionalAuth, + async ( + { + body: { type = "bech32", liquidAddress, id, invoice, user, tx }, + user: me + }, + res + ) => { let { blindkey, currency, @@ -71,49 +32,24 @@ app.post("/invoice", optionalAuth, async (req, res, next) => { network, request_id } = invoice; - let address, unconfidential, text; + let text; if (amount < 0) throw new Error("amount out of range"); if (tip > 5 * amount || tip < 0) throw new Error("tip amount out of range"); + tip = tip || 0; - if (!user) ({ user } = req); - else { - user = await db.User.findOne({ - where: { - username: user.username - }, - include: { - model: db.Account, - as: "account" - } - }); - } + if (!user) user = me; if (!user) throw new Error("user not provided"); + + user = await g(`user:${user.id}`); + if (!currency) currency = user.currency; if (!rate) rate = store.rates[currency]; if (amount < 0) throw new Error("invalid amount"); - if (user.account.pubkey) { - let { address, confidentialAddress } = await deriveAddress( - user.account, - type - ); - if (confidentialAddress) { - address = confidentialAddress; - unconfidential = address; - } else { - address = address; - } - } else if (network !== "lightning") { - address = await { bitcoin: bc, liquid: lq }[network].getNewAddress(); - if (network === "liquid") - ({ unconfidential } = await lq.getAddressInfo(address)); - } - invoice = { ...invoice, - account_id: user.account.id, - address, + id: v4(), amount, currency, rate, @@ -122,83 +58,29 @@ app.post("/invoice", optionalAuth, async (req, res, next) => { user_id: user.id }; - if (network === "lightning") { - invoice.text = await derivePayRequest(invoice); - } else { - invoice.text = bip21(invoice, user.account); - } - - if (liquidAddress) { - if (network === "lightning") { - l("conversion request for", liquidAddress, invoice.text); - store.convert[invoice.text] = { address: liquidAddress, tx }; - } else if (network === "liquid") { - l("conversion request for", liquidAddress, invoice.unconfidential); - store.convert[invoice.unconfidential] = { address: liquidAddress, tx }; - } else { - l("conversion request for", liquidAddress, invoice.address); - store.convert[invoice.address] = { address: liquidAddress, tx }; - } - } + invoice.text = await derivePayRequest(invoice); l( "creating invoice", user.username, - invoice.network, - invoice.amount, - invoice.tip, - invoice.currency, - invoice.text && `${invoice.text.substr(0, 8)}..${invoice.text.substr(-6)}` + network, + amount, + tip, + currency, + `${text.substr(0, 8)}..${text.substr(-6)}` ); - if (!invoice.tip) invoice.tip = 0; - - invoice = await db.Invoice.create(invoice); - store.addresses[invoice.address] = user.username; - if (invoice.unconfidential) { - store.addresses[invoice.unconfidential] = user.username; - if (blindkey) await lq.importBlindingKey(invoice.address, blindkey); - } + await rd.lPush(`${id}:invoices`, invoice.id); if (request_id) { - let request = await db.Request.findOne({ - where: { id: request_id }, - - include: { - model: db.User, - as: "requester", - attributes: ["username"] - } - }); + let request = await g(`request:${request_id}`); + let { invoice_id: prev } = request; + request.invoice_id = invoice.id; + await s(`request:${request_id}`, request); - if (request) { - let existing = request.invoice_id; - request.invoice_id = invoice.id; - await request.save(); - - if (!existing) - emit(request.requester.username, "invoice", { - amount: invoice.amount, - currency: invoice.currency, - rate: invoice.rate, - request_id, - uuid: invoice.uuid, - user: { username: user.username, profile: user.profile } - }); - } + if (!prev) emit(request.requester.username, "invoice", invoice); } res.send(invoice); - } catch (e) { - err(e.message, e.stack); - res.code(500).send(`Problem during invoice creation: ${e.message}`); - } -}); - -app.post( - "/:username/:network/invoice", - optionalAuth, - async (req, res, next) => { - let { network, username } = req.params; } ); diff --git a/routes/lightning/channel.js b/routes/lightning/channel.js deleted file mode 100644 index d5d5b7b2..00000000 --- a/routes/lightning/channel.js +++ /dev/null @@ -1,29 +0,0 @@ -import axios from "axios"; -import ln from "$lib/ln"; - -export default async (req, res) => { - const { params } = req.body; - const [public_key, socket] = params.uri.split("@"); - - l("connecting to peer", req.user.username, public_key, socket); - let result; - - const { callback, k1 } = params; - let remoteid; - try { - remoteid = (await ln.getinfo()).id; - } catch (e) { - err("problem getting lightning node info", e.message); - return res.code(500).send(e.message); - } - - let url = `${callback}?k1=${k1}&remoteid=${remoteid}&private=0`; - - try { - let response = await axios.get(url); - res.send(response.data); - } catch (e) { - err("problem sending channel request", e.message); - return res.code(500).send({ status: "ERROR", reason: e.message }); - } -}; diff --git a/routes/lightning/channelRequest.js b/routes/lightning/channelRequest.js deleted file mode 100644 index 74e4cbba..00000000 --- a/routes/lightning/channelRequest.js +++ /dev/null @@ -1,24 +0,0 @@ -import { lnurlServer } from "$routes/lnurl"; -import { err } from "$lib/logging"; - -export const channelRequest = async (req, res) => { - let { localAmt, pushAmt } = req.body; - - pushAmt = 0; - - try { - if (localAmt < 20000) - throw new Error("amount must be greater than 20000 SAT"); - if (localAmt > 1000000) throw new Error("amount must be <= 1000000"); - - const result = await lnurlServer.generateNewUrl("channelRequest", { - localAmt, - pushAmt - }); - - res.send(result); - } catch (e) { - err("problem generating channel request", e.message); - res.code(500).send(e.message); - } -}; diff --git a/routes/lightning/index.js b/routes/lightning/index.js index b4611ef5..ddc10bfe 100644 --- a/routes/lightning/index.js +++ b/routes/lightning/index.js @@ -1,11 +1,9 @@ -import channel from "./channel"; import invoice from "./invoice"; import query from "./query"; import send from "./send"; import parse from "./parse"; export default { - channel, invoice, query, send, diff --git a/routes/requests.js b/routes/requests.js index 0b3832e8..bea8f7fd 100644 --- a/routes/requests.js +++ b/routes/requests.js @@ -1,92 +1,23 @@ import app from "$app"; import { auth } from "$lib/passport"; import { emit } from "$lib/sockets"; +import { g, rd } from "$lib/redis"; -app.get("/request/:id", auth, async (req, res) => { +app.get("/request/:id", auth, async ({ params: { id } }, res) => { try { - let request = await db.Request.findOne({ - where: { id: req.params.id }, - include: [ - { - attributes: ["username", "profile"], - model: db.User, - as: "recipient" - }, - { - attributes: ["username", "profile"], - model: db.User, - as: "requester" - }, - { - model: db.Invoice, - as: "invoice" - } - ] - }); - - res.send({ request }); + res.send({ request: await g(id) }); } catch (e) { console.log(e); res.code(500).send(e.message); } }); -app.get("/requests", auth, async (req, res) => { +app.get("/requests", auth, async ({ user: { uuid } }, res) => { try { const day = new Date(new Date().setDate(new Date().getDate() - 1)); - let invoices = ( - await db.Request.findAll({ - where: { - [Op.or]: { - recipient_id: req.user.id, - requester_id: req.user.id - }, - createdAt: { [Op.gt]: day } - }, - order: [["createdAt", "DESC"]], - include: [ - { - model: db.Invoice, - as: "invoice", - where: { received: { [Op.lt]: col("invoice.amount") } }, - include: { - model: db.User, - as: "user", - attributes: ["username", "profile"] - } - }, - { - model: db.User, - as: "requester", - attributes: ["username", "profile"] - } - ] - }) - ) - .map( - r => - r.invoice && { - request_id: r.id, - requester: r.requester.get({ plain: true }), - ...r.invoice.get({ plain: true }) - } - ) - .filter(r => r); - - let requests = await db.Request.findAll({ - where: { - recipient_id: req.user.id, - createdAt: { [Op.gt]: day }, - invoice_id: { [Op.eq]: null } - }, - order: [["createdAt", "DESC"]], - include: { - attributes: ["username", "profile"], - model: db.User, - as: "requester" - } - }); + let invoices = await rd.lRange(`${uuid}:invoices`, 0, -1); + let requests = await rd.lRange(`${uuid}:requests`, 0, -1); res.send({ invoices, requests }); } catch (e) { @@ -95,41 +26,32 @@ app.get("/requests", auth, async (req, res) => { } }); -app.post("/requests", auth, async (req, res) => { - try { - let { recipient: username, ...params } = req.body; - let { id: recipient_id } = await db.User.findOne({ where: { username } }); +app.post( + "/requests", + auth, + async ( + { body: { recipient, ...params }, user: { username, profile } }, + res + ) => { + let { id: recipient_id } = await g(`user:${recipient}`); - let request = await db.Request.create({ recipient_id, ...params }); - request = request.get({ plain: true }); + let request = { recipient_id, ...params }; request.requester = { - username: req.user.username, - profile: req.user.profile + username, + profile }; - emit(username, "request", request); + + emit(recipient, "request", request); res.send(request); - } catch (e) { - console.log(e); - res.code(500).send(e.message); } -}); - -app.post("/requests/delete", auth, async (req, res) => { - try { - let r = await db.Request.findOne({ - where: { - id: req.body.request_id, - [Op.or]: { requester_id: req.user.id, recipient_id: req.user.id } - } - }); - - if (!r) throw new Error("request not found"); - await r.destroy(); +); +app.post( + "/requests/delete", + auth, + async ({ body: { request_id }, user: { id } }, res) => { + await rd.lrem(`user:${id}:requests`, request_id); res.send(); - } catch (e) { - console.log(e); - res.code(500).send(e.message); } -}); +); diff --git a/routes/users.js b/routes/users.js index 4a01cc1e..8f0b9106 100644 --- a/routes/users.js +++ b/routes/users.js @@ -1,5 +1,5 @@ import app from "$app"; -import redis from "$lib/redis"; +import { g, s } from "$lib/redis"; import config from "$config"; import store from "$lib/store"; import { auth, optionalAuth } from "$lib/passport"; @@ -13,30 +13,25 @@ import { emit } from "$lib/sockets"; import register from "$lib/register"; import { requirePin } from "$lib/utils"; import got from "got"; -import { bech32 } from "bech32"; - -const { encode, decode, fromWords, toWords } = bech32; const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {}); app.get("/me", auth, async (req, res) => { try { - let user = req.user.get({ plain: true }); - user.haspin = !!user.pin; - res.send(pick(user, ...whitelist)); + res.send(pick(req.user, ...whitelist)); } catch (e) { console.log("problem fetching user", e); res.code(500).send(e.message); } }); -app.get("/users/:key", async (req, res) => { +app.get("/users/:key", async ({ params: { key } }, res) => { try { if (key.startsWith("npub")) { key = Buffer.from(fromWords(decode(key).words)).toString("hex"); } - user = JSON.parse(await redis.get(`user:${key}`)); + let user = await g(`user:${key}`); if (!user && key.length === 64) { user = { @@ -46,6 +41,7 @@ app.get("/users/:key", async (req, res) => { }; } + console.log(user) if (!user) return res.code(500).send("User not found"); let whitelist = [ @@ -69,7 +65,7 @@ app.get("/users/:key", async (req, res) => { app.post("/register", async (req, res) => { try { - const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress; + const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress; let { cipher, pubkey, password, username, salt } = req.body.user; let user = { @@ -129,14 +125,6 @@ app.post("/2fa", auth, async (req, res) => { res.send({}); }); -app.get("/exists", async (req, res) => { - let exists = await db.User.findOne({ - where: { username: req.query.username } - }); - - res.send(!!exists); -}); - app.post("/user", auth, async (req, res) => { try { let { user } = req; @@ -303,6 +291,7 @@ app.post("/accounts", auth, async (req, res) => { let login = async (req, res) => { try { const { params, sig, key, password, username, token: twofa } = req.body; + l("logging in", username); if (sig) { const { callback } = params; @@ -340,18 +329,17 @@ let login = async (req, res) => { l( "login", username, - req.headers["x-forwarded-for"] || req.connection.remoteAddress + req.headers["x-forwarded-for"] || req.socket.remoteAddress ); let payload = { username, 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(); - user.keys = await user.getKeys(); user = pick(user, ...whitelist); res.send({ user, token }); } catch (e) { - err("login error", e.message, req.connection.remoteAddress); + console.log(e); + err("login error", e.message, req.socket.remoteAddress); res.code(401).send({}); } }; @@ -424,35 +412,13 @@ app.post("/otpsecret", auth, async function(req, res) { } }); -app.get("/contacts", auth, async function(req, res) { - try { - let contacts = await db.Payment.findAll({ - where: { - user_id: req.user.id, - with_id: { [Sequelize.Op.ne]: null } - }, - include: { - attributes: ["username", "profile", "uuid"], - model: db.User, - as: "with" - }, - attributes: [ - [Sequelize.fn("max", Sequelize.col("payments_model.createdAt")), "last"] - ], - group: ["with_id"], - order: [[{ model: db.User, as: "with" }, "username", "ASC"]] - }); - - res.send( - contacts.map(c => { - c = c.get({ plain: true }); - return { ...c.with, last: c.last }; - }) - ); - } catch (e) { - console.log(e); - res.code(500).send(e.message); - } +app.get("/contacts", auth, async function({ user: { uuid } }, res) { + let payments = await g(`${uuid}:payments`) || []; + res.send( + Promise.all( + [...new Set(payments.map(p => p.with_id))].map(id => g(`user:${id}`)) + ) + ); }); app.post("/checkPassword", auth, async function(req, res) { |
