aboutsummaryrefslogtreecommitdiffstats
path: root/routes
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-01-11 22:09:48 -0800
committerAdam Soltys <[email protected]>2023-01-12 15:44:13 -0800
commitc3565838644123e77881ff4f8536792f074047b9 (patch)
tree96da43fd19940d2f0836e43a511f0a1fb365044d /routes
parentded2c69ce89438326523a512b570be6eee4b23f0 (diff)
downloadcoinos-server-c3565838644123e77881ff4f8536792f074047b9.tar.gz
coinos-server-c3565838644123e77881ff4f8536792f074047b9.zip
migrating to redis
Diffstat (limited to 'routes')
-rw-r--r--routes/invoices.js188
-rw-r--r--routes/lightning/channel.js29
-rw-r--r--routes/lightning/channelRequest.js24
-rw-r--r--routes/lightning/index.js2
-rw-r--r--routes/requests.js130
-rw-r--r--routes/users.js68
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) {