-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
122 lines (103 loc) · 4.29 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const rp = require('request-promise')
const bitcore = require('bitcore-lib')
const Message = require('bitcore-message')
const fs = require('fs')
const util = require('util')
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
const app = express()
const auth = 'Basic ' + Buffer.from(config.user + ':' + config.password).toString('base64')
app.use(cors())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.post('/', async function (req, res) {
const { address, addressSig, prevaddressSig } = req.body
const name = typeof req.body.name === 'string' ? req.body.name.toLowerCase() : ''
let { prevaddress } = req.body
let addressVerification = ''
let prevaddressVerification = ''
if (!name || !address || !addressSig) {
return res.status(400).json({ error: 'Missing required fields, please ensure you included an alias, address, and a signature.', address: address || 'Missing', name: name || 'Missing', addressSig: addressSig || 'Missing', prevaddress: prevaddress || 'Missing', prevaddressSig: prevaddressSig || 'Missing' })
}
// Verify Email Address
if (/[^a-zA-Z0-9.]/.test(name)) {
return res.status(400).json({ error: 'Username can only contain alphanumeric characters (a-z and 0-9) and dots (.)', name, address, addressSig, prevaddress, prevaddressSig })
}
// Verify NavCoin Addresses
if (!verifyAddress(address)) {
return res.status(400).json({ error: 'Invalid NavCoin address: ' + address, name, address, addressSig, prevaddress, prevaddressSig })
}
try {
prevaddress = await checkDNS(name)
} catch (err) {
return res.status(500).json({ error: 'Could not reach DNS server. Try again later.', name, address, addressSig, prevaddress, prevaddressSig })
}
// If we have a prevaddress..
if (prevaddress) {
// .. we check if it's invalid and error.
if (!verifyAddress(prevaddress)) {
return res.status(400).json({ error: 'Invalid NavCoin address' + prevaddress, name, address, addressSig, prevaddress, prevaddressSig })
}
// Return error if incorrectly signed.
// Need try catch because bitcore doesnt handle invalid sigs.
try {
prevaddressVerification = Message(name + '@nav.community').verify(prevaddress, prevaddressSig)
if (!prevaddressVerification) {
throw new Error()
}
} catch (err) {
return res.status(400).json({ error: 'Previous Address Signature incorrect. Someone else may already own this alias.', name, address, addressSig, prevaddress, prevaddressSig })
}
}
// Check address signature
// We need try catch because bitcore message doesn't handle invalid sigs
try {
addressVerification = Message(name + '@nav.community').verify(address, addressSig)
if (!addressVerification) { throw new Error() }
} catch (err) {
return res.status(400).json({ error: 'Address Signature incorrect', name, address, addressSig, prevaddress, prevaddressSig })
}
// Update the DNS server
rp({
uri: util.format(config.url, `${name}.nav.community`, 'txt'),
method: 'PUT', headers: { 'Authorization': auth },
body: `oa1:nav recipient_address=${address};`
}).then(() => {
return res.status(200).json({ openAlias: `${name}.nav.community`, address, name })
}).catch(() => {
return res.status(500).json({ error: 'Unknown error. Please try again later', name, address, addressSig, prevaddress, prevaddressSig })
})
})
const checkDNS = async (name) => {
return new Promise(async function (resolve, reject) {
try {
const response = await rp({
uri: util.format(config.url, `${name}.nav.community`, 'txt'),
method: 'GET', headers: { 'Authorization': auth },
})
const json = JSON.parse(response)
if (json.length > 0) {
const oaAddr = json[0].value.split('oa1:nav recipient_address=')[1].split(';')[0]
if (oaAddr) {
resolve(oaAddr)
}
}
resolve('')
} catch (err) {
reject(err)
}
})
}
const verifyAddress = (address) => {
try {
new bitcore.Address(address)
} catch (e) {
return false
}
return true
}
app.listen(process.env.PORT || config.port, function () {
console.log(`Server started on localhost:${process.env.PORT || config.port}`)
})