aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRan Guin <[email protected]>2021-05-13 15:31:34 -0700
committerRan Guin <[email protected]>2021-05-13 15:31:34 -0700
commit196a9439fb4cabe30297800ac0309f6f8d0c2919 (patch)
treedf5adabeaa0435d16dba538b165653de71d24c18
parentb49ac39b07ad67529a67ed3a18639472cdf01262 (diff)
parent4d2379b801ed0a95e8538a64873a0be503e74672 (diff)
downloadcoinos-server-196a9439fb4cabe30297800ac0309f6f8d0c2919.tar.gz
coinos-server-196a9439fb4cabe30297800ac0309f6f8d0c2919.zip
Merge branch 'master' of https://github.com/asoltys/coinos-server
-rw-r--r--lib/rates.js11
-rw-r--r--lib/sockets.js3
-rw-r--r--routes/funding.js167
-rw-r--r--routes/invoices.js1
-rw-r--r--routes/lightning/receive.js1
-rw-r--r--routes/liquid/receive.js18
-rw-r--r--routes/liquid/send.js2
-rw-r--r--routes/users.js2
8 files changed, 133 insertions, 72 deletions
diff --git a/lib/rates.js b/lib/rates.js
index fdb7f5ac..80c22bf0 100644
--- a/lib/rates.js
+++ b/lib/rates.js
@@ -27,7 +27,9 @@ let fetchRates;
try {
let {
data: { rates: fx }
- } = await axios.get(`http://data.fixer.io/api/latest?access_key=${config.fixer}`);
+ } = await axios.get(
+ `http://data.fixer.io/api/latest?access_key=${config.fixer}`
+ );
let USD = fx["USD"];
Object.keys(fx).map(k => {
fx[k] = parseFloat((fx[k] / fx["USD"]).toFixed(6));
@@ -44,6 +46,13 @@ let fetchRates;
setTimeout(fetchRates, 7200000);
})();
+app.get(
+ "/rates",
+ ah(async (req, res, next) => {
+ res.send(app.get("rates"));
+ })
+);
+
setInterval(() => {
broadcast("rate", app.get("last"));
}, 1000);
diff --git a/lib/sockets.js b/lib/sockets.js
index b6a806ff..931a9d23 100644
--- a/lib/sockets.js
+++ b/lib/sockets.js
@@ -92,10 +92,9 @@ wss.on("connection", function(ws, req) {
case "login":
let token = data;
- if (differenceInSeconds(new Date(), subSeconds(lastSeen[token], 5)) < 2) return;
+ if (differenceInSeconds(new Date(), lastSeen[token]) < 5) return;
lastSeen[token] = new Date();
-
try {
if (!token || token === "null") return ws.close();
const username = jwt.decode(token).username;
diff --git a/routes/funding.js b/routes/funding.js
index d9af4da7..b398d341 100644
--- a/routes/funding.js
+++ b/routes/funding.js
@@ -1,3 +1,4 @@
+const mailgun = require("mailgun-js")(config.mailgun);
const multer = require("multer");
const storage = multer.diskStorage({
@@ -6,8 +7,8 @@ const storage = multer.diskStorage({
},
filename: (req, file, cb) => {
const parts = file.originalname.split(".");
- const ext = parts.length > 1 ? parts[parts.length - 1] : 'bin';
- cb(null, `${req.user.username}-${file.fieldname}.${ext}`)
+ const ext = parts.length > 1 ? parts[parts.length - 1] : "bin";
+ cb(null, `${req.user.username}-${file.fieldname}.${ext}`);
}
});
@@ -21,80 +22,112 @@ const upload = multer({
}
});
-app.post("/id", auth, upload.single("id"), ah(async (req, res) => {
- const { user } = req;
- if (user.verified === 'proof') user.verified = 'pending';
- else user.verified = 'id';
- await user.save();
- emit(user.username, "user", user);
+app.post(
+ "/id",
+ auth,
+ upload.single("id"),
+ ah(async (req, res) => {
+ const { user } = req;
+ if (user.verified === "proof") user.verified = "pending";
+ else user.verified = "id";
+ await user.save();
+ emit(user.username, "user", user);
- res.end();
-}));
+ let data = {
+ ...config.mail,
+ subject: "KYC Documents",
+ text: `ID uploaded for ${user.username}`,
+ };
+
+ mailgun.messages().send(data);
+ l.info("id uploaded", user.username);
+
+ res.end();
+ })
+);
-app.post("/proof", auth, upload.single("proof"), ah(async (req, res) => {
- const { user } = req;
- if (user.verified === 'id') user.verified = 'pending';
- else user.verified = 'proof';
- await user.save();
- emit(user.username, "user", user);
+app.post(
+ "/proof",
+ auth,
+ upload.single("proof"),
+ ah(async (req, res) => {
+ const { user } = req;
+ if (user.verified === "id") user.verified = "pending";
+ else user.verified = "proof";
+ await user.save();
+ emit(user.username, "user", user);
+ l.info("id proof uploaded", user.username);
- res.end();
-}));
+ res.end();
+ })
+);
-app.post("/funding", auth, ah(async (req, res) => {
- try {
- let { id, amount, code } = req.body;
+app.post(
+ "/funding",
+ auth,
+ ah(async (req, res) => {
+ try {
+ let { id, amount, code } = req.body;
- if (!code) {
- code = '';
- let d = 'ABCDEFGHIJKLMNPQRSTUVWXYZ23456789';
- let l = d.length;
- for (let i = 0; i < 8; i++) {
- code += d.charAt(Math.floor(Math.random() * l));
+ if (!code) {
+ code = "";
+ let d = "ABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
+ let l = d.length;
+ for (let i = 0; i < 8; i++) {
+ code += d.charAt(Math.floor(Math.random() * l));
+ }
}
- }
- let params = {
- user_id: req.user.id,
- amount,
- code,
- };
+ let params = {
+ user_id: req.user.id,
+ amount,
+ code
+ };
- let deposit;
- if (id) {
- if (!parseFloat(amount) || parseFloat(amount) < 0) throw new Error("Invalid amount");
- deposit = await db.Deposit.findOne({ where: { id } })
- deposit.update(params);
- await deposit.save();
- } else {
- deposit = await db.Deposit.create(params);
- }
+ let deposit;
+ if (id) {
+ if (!parseFloat(amount) || parseFloat(amount) < 0)
+ throw new Error("Invalid amount");
+ deposit = await db.Deposit.findOne({ where: { id } });
+ deposit.update(params);
+ await deposit.save();
+ } else {
+ deposit = await db.Deposit.create(params);
+ }
- res.send(deposit);
- } catch(e) {
- l.error("funding error", e.message);
- res.status(500).send("Funding request failed");
- }
-}));
+ res.send(deposit);
+ } catch (e) {
+ l.error("funding error", e.message);
+ res.status(500).send("Funding request failed");
+ }
+ })
+);
-app.post("/withdrawal", auth, ah(async (req, res) => {
- try {
- const { account, amount, email, institution, transit, notes } = req.body;
- if (!parseFloat(amount) || parseFloat(amount) < 0) throw new Error("Invalid amount");
+app.post(
+ "/withdrawal",
+ auth,
+ ah(async (req, res) => {
+ try {
+ const { account, amount, email, institution, transit, notes } = req.body;
+ if (!parseFloat(amount) || parseFloat(amount) < 0)
+ throw new Error("Invalid amount");
- await db.Withdrawal.create({
- user_id: req.user.id,
- account,
- amount,
- email,
- institution,
- transit,
- notes,
- });
+ await db.Withdrawal.create({
+ user_id: req.user.id,
+ account,
+ amount,
+ email,
+ institution,
+ transit,
+ notes
+ });
- res.end();
- } catch(e) {
- l.error("withdrawal error", e.message);
- res.status(500).send("Withdrawal request failed");
- }
-}));
+ res.end();
+ } catch (e) {
+ l.error("withdrawal error", e.message);
+ res.status(500).send("Withdrawal request failed");
+ }
+ })
+);
diff --git a/routes/invoices.js b/routes/invoices.js
index cdf8ca91..a1928287 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -40,6 +40,7 @@ app.post(
if (!user) throw new Error("user not provided");
if (!invoice.currency) invoice.currency = user.currency;
if (!invoice.rate) invoice.rate = app.get("rates")[invoice.currency];
+ if (invoice.tip > invoice.amount || invoice.tip > 1000000) throw new Error("tip is too large")
invoice.user_id = user.id;
invoice.account_id = user.account_id;
diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js
index 8778bb22..325f7092 100644
--- a/routes/lightning/receive.js
+++ b/routes/lightning/receive.js
@@ -18,6 +18,7 @@ const handlePayment = async msg => {
const { text: hash, currency, memo, rate, tip, user_id } = invoice;
const amount = parseInt(msg.amt_paid_sat) - tip;
+ if (amount > 10000000 || amount < 0) throw new Error("amount out of range");
account = await db.Account.findOne({
where: {
diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js
index 3ce6ca9a..f6a78cfa 100644
--- a/routes/liquid/receive.js
+++ b/routes/liquid/receive.js
@@ -287,6 +287,7 @@ setInterval(async () => {
for (let i = 0; i < arr.length; i++) {
const hash = arr[i];
+ let account, address, user, total;
await db.transaction(async transaction => {
let p = await db.Payment.findOne({
where: { hash, confirmed: 0, received: 1 },
@@ -304,7 +305,7 @@ setInterval(async () => {
transaction
});
- const { user } = p;
+ ({ account, address, user } = p);
if (p && p.account) {
let total = p.amount + p.tip;
@@ -340,6 +341,21 @@ setInterval(async () => {
delete queue[hash];
});
+
+ let c = convert[address];
+ if (c) {
+ let { tx } = c;
+ user.account = account;
+
+ delete queue[hash];
+
+ await sendLiquid({
+ address,
+ user,
+ tx,
+ limit: total
+ });
+ }
}
} catch (e) {
l.error("problem processing queued liquid transaction", e.message);
diff --git a/routes/liquid/send.js b/routes/liquid/send.js
index 0729370c..b80471b0 100644
--- a/routes/liquid/send.js
+++ b/routes/liquid/send.js
@@ -158,6 +158,6 @@ module.exports = ah(async (req, res) => {
res.send(await sendLiquid({ user, address, memo, tx }));
} catch (e) {
l.error("problem sending liquid", user.username, e.message);
- return res.status(500).send(e.message);
+ return res.status(500).send(e);
}
});
diff --git a/routes/users.js b/routes/users.js
index b02e10af..44478c0a 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -161,6 +161,7 @@ app.post(
return res.status(500).send("Username taken");
} else {
sockets[username] = sockets[user.username];
+ if (user.username !== username) l.info("changing username", user.username, username);
user.username = username;
token = jwt.sign({ username }, config.jwt);
@@ -614,6 +615,7 @@ app.post(
"/redeem",
optionalAuth,
ah(async function(req, res) {
+ return res.status(500).send("Vouchers temporarily disabled");
const { redeemcode } = req.body;
if (!redeemcode) fail("no code provided");