functional
This commit is contained in:
parent
1ffe5d8f0f
commit
b161f0892e
1
.gitignore
vendored
1
.gitignore
vendored
@ -116,3 +116,4 @@ dist
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
config.js
|
19
config template.js
Normal file
19
config template.js
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
//Edit the values in this file and rename it to config.js or everyone will (rightfully) laugh at you when you ask for help.
|
||||
|
||||
config = {
|
||||
avalonNode: "https://avalon.tld/",
|
||||
database: "keyStore",
|
||||
jwtSecret: "jwtSecretjwtSecretjwtSecretjwtSecret" || process.env.jwtSecret,
|
||||
secret: "secretsecretsecretsecret" || process.env.jwtSecret,
|
||||
mongoUrl: "mongodb://mongodbserver/",
|
||||
expressPort: 3000,
|
||||
fee: 0,
|
||||
discordUser: "userName#1970",
|
||||
accountCreator: {
|
||||
username: "accountCreatorUsername",
|
||||
privKey: "",
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = config
|
70
index.js
Normal file
70
index.js
Normal file
@ -0,0 +1,70 @@
|
||||
config = require("./config.js")
|
||||
register = require("./register.js")
|
||||
login = require("./login.js")
|
||||
txHandler = require("./txHandler.js")
|
||||
require("./peroidicActions/checkPayment.js")
|
||||
require("./peroidicActions/pruneUnpaidAccounts.js")
|
||||
|
||||
express = require('express')
|
||||
jwt = require('jsonwebtoken')
|
||||
bodyParser = require('body-parser')
|
||||
javalon = require("javalon")
|
||||
|
||||
javalon.init({api: config.avalonNode.slice(0, -1)})
|
||||
|
||||
app = express()
|
||||
app.use(bodyParser.json(),function (req, res, next) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*')
|
||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST')
|
||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
|
||||
res.setHeader('Content-Type', 'application/json')
|
||||
res.setHeader('Access-Control-Allow-Credentials', true)
|
||||
next()
|
||||
})
|
||||
|
||||
const authenticateJWT = (req, res, next) => {
|
||||
const authHeader = req.headers.authorization;
|
||||
|
||||
if (authHeader) {
|
||||
const token = authHeader.split(' ')[1];
|
||||
jwt.verify(token, config.jwtSecret, (err, user) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
return res.send({"Error": "Auth Failure"})
|
||||
}
|
||||
|
||||
req.user = user
|
||||
next();
|
||||
});
|
||||
} else {
|
||||
res.redirect(401, "/");
|
||||
}
|
||||
}
|
||||
|
||||
app.post('/register', function (req, res) {
|
||||
register(req.body.username, req.body.password).then(x => {
|
||||
res.send({"Message": x})
|
||||
}).catch( e => {
|
||||
res.send({"Error": e})
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/login', function (req, res) {
|
||||
login(req.body.username, req.body.password).then(x => {
|
||||
res.send({"accessToken":x})
|
||||
}).catch( e => {
|
||||
res.send({"Message": e})
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/submit',authenticateJWT, function (req, res) {
|
||||
txHandler(req.body.tx, req.user).then(x => {
|
||||
res.send({"Message": x})
|
||||
}).catch( e => {
|
||||
res.send({"Message": e})
|
||||
})
|
||||
})
|
||||
|
||||
console.log("Up on: "+config.expressPort)
|
||||
app.listen(config.expressPort)
|
29
login.js
Normal file
29
login.js
Normal file
@ -0,0 +1,29 @@
|
||||
mongo = require("./mongoHelp")
|
||||
config = require("./config.js")
|
||||
crypto = require('crypto')
|
||||
jwt = require('jsonwebtoken')
|
||||
|
||||
accessTokenSecret = config.secret;
|
||||
|
||||
function login(username, password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
mongo.get(config.database, "users", {"username":username}).then(userArr => {
|
||||
hashedStr = crypto.createHmac('sha256', config.secret).update(password).digest('hex')
|
||||
if (userArr.length != 1){
|
||||
//No user is registered to that address
|
||||
reject("Error")
|
||||
} else if (hashedStr != userArr[0].password){
|
||||
// Password Doesn't Match
|
||||
reject("Error")
|
||||
} else {
|
||||
const accessToken = jwt.sign({
|
||||
username: userArr[0].username,
|
||||
}, config.jwtSecret, { expiresIn: '7d' })
|
||||
resolve(accessToken)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
module.exports = login
|
58
mongoHelp.js
Normal file
58
mongoHelp.js
Normal file
@ -0,0 +1,58 @@
|
||||
var MongoClient = require('mongodb').MongoClient
|
||||
config = require("./config")
|
||||
|
||||
var url = config.mongoUrl
|
||||
var options= {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
promiseLibrary: global.Promise}
|
||||
|
||||
function put(db,collection, object){
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
client.db(db).collection(collection).insertOne(object).then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
exports.put = put
|
||||
|
||||
function get(db, collection, object){
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
return client.db(db).collection(collection).find(object).toArray().then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
exports.get = get
|
||||
|
||||
function getUnique(db, collection, field,object){
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
return client.db(db).collection(collection).distinct(field,object).then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
|
||||
exports.getUnique = getUnique
|
||||
|
||||
function aggregate(db,collection,agg){
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
return client.db(db).collection(collection).aggregate(agg).toArray().then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
exports.aggregate = aggregate
|
||||
|
||||
function deleteOne(db, collection, object) {
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
client.db(db).collection(collection).deleteOne(object).then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
exports.deleteOne = deleteOne
|
||||
|
||||
function update(db, collection, search,update) {
|
||||
const client = new MongoClient(url, options)
|
||||
client.connect()
|
||||
client.db(db).collection(collection).updateOne(search,{$set:update}).then((value) =>{client.close();return value})
|
||||
}
|
||||
|
||||
exports.update = update
|
||||
|
51
peroidicActions/checkPayment.js
Normal file
51
peroidicActions/checkPayment.js
Normal file
@ -0,0 +1,51 @@
|
||||
mongo = require("../mongoHelp.js")
|
||||
config = require("../config.js")
|
||||
|
||||
javalon = require("javalon")
|
||||
|
||||
function checkPayment(){
|
||||
javalon.getAccountHistory(config.accountCreator.username, 0, (err, blocks) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
} else {
|
||||
blocks.forEach(element => {
|
||||
if (element.txs[0].type == 3) {
|
||||
if (element.txs[0].data.memo.length > 8){
|
||||
mongo.get(config.database, "users", {_id: element.txs[0].data.memo}).then(userArr => {
|
||||
if (userArr.length != 1){
|
||||
console.log("UserArray too long, this could indicate duplicate IDs which would be bad")
|
||||
} else {
|
||||
console.log(element.txs[0].data.amount , userArr[0].price)
|
||||
if (element.txs[0].data.memo == userArr[0]._id && element.txs[0].data.amount >= userArr[0].price && userArr[0].status == "Inactive" ){
|
||||
id = userArr[0]._id
|
||||
|
||||
tx = {
|
||||
type: 0,
|
||||
data: {
|
||||
pub: userArr[0].keys.pub,
|
||||
name: userArr[0].username
|
||||
}
|
||||
}
|
||||
signedTx = javalon.sign(config.accountCreator.privKey,config.accountCreator.username, tx)
|
||||
javalon.sendTransaction(signedTx, function(err, res) {
|
||||
if (err){
|
||||
console.log(err)
|
||||
} else {
|
||||
userArr[0].status = "Active"
|
||||
mongo.update(config.database, "users", {_id: id}, userArr[0])
|
||||
console.log(res)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
setInterval(checkPayment, 60000)
|
||||
|
23
peroidicActions/pruneUnpaidAccounts.js
Normal file
23
peroidicActions/pruneUnpaidAccounts.js
Normal file
@ -0,0 +1,23 @@
|
||||
mongo = require("../mongoHelp.js")
|
||||
config = require("../config.js")
|
||||
|
||||
javalon = require("javalon")
|
||||
|
||||
function pruneUnpaidAccounts(){
|
||||
agg = [ {'$match': {
|
||||
timeLimit: { $lt: Date.now()}
|
||||
}},
|
||||
{'$match': {
|
||||
status: "Inactive"
|
||||
}}]
|
||||
mongo.aggregate(config.database, "users", agg).then(oldArr => {
|
||||
oldArr.forEach(element => {
|
||||
mongo.deleteOne(config.database, "users", {_id:element._id})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
setInterval(pruneUnpaidAccounts, 3600000)
|
47
register.js
Normal file
47
register.js
Normal file
@ -0,0 +1,47 @@
|
||||
mongo = require("./mongoHelp.js")
|
||||
config = require("./config.js")
|
||||
accountPrice = require("./utils/accountPrice.js")
|
||||
|
||||
crypto = require("crypto")
|
||||
uuidv4 = require('uuid/v4')
|
||||
javalon = require("javalon")
|
||||
|
||||
|
||||
function register(username, password){
|
||||
return new Promise((resolve, reject) => {
|
||||
userObj = {
|
||||
_id: uuidv4(),
|
||||
username: username,
|
||||
status: "Inactive",
|
||||
timeLimit: Date.now()+604800000
|
||||
}
|
||||
|
||||
mongo.get(config.database, "users", {"username":username}).then(resArr => {
|
||||
if (resArr.length != 0 ){
|
||||
reject("Username is awaiting creation and will be available at "+new Date(resArr[0].timeLimit)+" if it remains unpaid")
|
||||
} else {
|
||||
javalon.getAccount(username, (err, account) => {
|
||||
if (!err) {
|
||||
reject("Username already exists")
|
||||
} else {
|
||||
userObj.keys = javalon.keypair()
|
||||
userObj.password = crypto.createHmac('sha256', config.secret).update(password).digest('hex')
|
||||
accountPrice(username).then(price => {
|
||||
console.log(price)
|
||||
console.log(parseFloat(price)+config.fee)
|
||||
userObj.price = parseFloat(price)+config.fee
|
||||
hPrice = (userObj.price/100)
|
||||
mongo.put(config.database, "users",userObj)
|
||||
resolve("Account setup: account will be accessible after sending "+hPrice+" DTC to "+config.accountCreator.username+" with a memo line of '"+ userObj._id+"' or contact "+config.discordUser+" on Discord to arrange alternate payment")
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = register
|
31
txHandler.js
Normal file
31
txHandler.js
Normal file
@ -0,0 +1,31 @@
|
||||
mongo = require("./mongoHelp.js")
|
||||
config = require("./config.js")
|
||||
javalon = require("javalon")
|
||||
|
||||
|
||||
function txHandler(tx,user){
|
||||
return new Promise((resolve,reject) => {
|
||||
mongo.get(config.database, "users", {"username": user.username}).then(userArr => {
|
||||
if (userArr[0].status == "Inactive"){
|
||||
reject(userArr[0].username+" has not been activated send "+parseFloat(userArr[0].price)/100+" DTC to "+config.accountCreator.username+" with a memo line of '"+ userArr[0]._id+"' or contact "+config.discordUser+" on Discord to arrange alternate payment")
|
||||
}
|
||||
else if (userArr.length == 0){
|
||||
reject("Something serious has gone wrong contact "+config.discordUser+" on Discord")
|
||||
} else {
|
||||
console.log(userArr[0])
|
||||
signedTx = javalon.sign(userArr[0].keys.priv, userArr[0].username, tx)
|
||||
javalon.sendTransaction(signedTx, function(err, res) {
|
||||
if (err){
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(res)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = txHandler
|
21
utils/accountPrice.js
Normal file
21
utils/accountPrice.js
Normal file
@ -0,0 +1,21 @@
|
||||
fetch = require("node-fetch")
|
||||
|
||||
config = require("../config.js")
|
||||
|
||||
function accountPrice(username){
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(config.avalonNode+"accountPrice/"+username, {
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(res => {
|
||||
resolve(res.text())
|
||||
}).catch(function(error) {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = accountPrice
|
Loading…
Reference in New Issue
Block a user