123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- const CashID = require('cashid')
- const PouchDB = require('pouchdb')
- const uuidv4 = require('uuid/v4')
- const moment = require('moment')
- // const superagent = require('superagent')
- /* Initialize slack. */
- const slack = require('./slack')
- /* Initialize CashID. */
- // const cashid = new CashID()
- const cashid = new CashID('api.apecs.dev', '/v1/cashid')
- /* Add Mango queries to PouchDB. */
- PouchDB.plugin(require('pouchdb-find'))
- /* Initialize databases. */
- const dbProfiles = new PouchDB('http://api:password@localhost:5984/profiles')
- const dbDetails = new PouchDB('http://api:password@localhost:5984/profiles_details')
- const dbSessions = new PouchDB('http://api:password@localhost:5984/apecs_sessions')
- /**
- * Add New Profile
- */
- const addNewProfile = async function (_address, _cashAccounts) {
- /* Initialize address. */
- let address = null
- /* Normalize address. */
- if (_address.includes('bitcoincash:')) {
- address = _address.slice(12)
- } else {
- address = _address
- }
- /* Set (mango) query. */
- const query = {
- selector: {
- 'account.type': 'bch',
- 'account.address': address,
- },
- // sort: [{'index':'asc'}]
- }
- /* Request data. */
- const result = await dbProfiles.find(query)
- console.log('ACCOUNT SEARCH', _address, _cashAccounts, result)
- /* Validate results. */
- if (!result || !result.docs || !result.docs.length > 0) {
- /* Initialize response. */
- let response = null
- /* Set profile id. */
- const profileid = uuidv4()
- /* Set account. */
- const account = {
- type: 'bch',
- address,
- }
- /* Set addresses. */
- const addresses = {
- bch: address
- }
- /* Initialize cash accounts. */
- let cashAccounts = null
- /* Validate cash accounts. */
- if (_cashAccounts.length > 0) {
- cashAccounts = _cashAccounts
- }
- /* Build new profile. */
- const profile = {
- _id: profileid,
- account,
- createdAt: moment().valueOf()
- }
- console.log('NEW PROFILE', profile)
- response = await dbProfiles.put(profile)
- .catch(err => console.error('NEW PROFILE ERROR:', err))
- console.log('ADD PROFILE RESPONSE', response)
- /* Build new profile details. */
- const details = {
- _id: profileid,
- addresses,
- cashAccounts,
- createdAt: moment().valueOf()
- }
- console.log('NEW PROFILE DETAILS', details)
- response = await dbDetails.put(details)
- .catch(err => console.error('NEW PROFILE DETAILS ERROR:', err))
- console.log('ADD PROFILE DETAIL RESPONSE', response)
- /* Send slack notification. */
- slack({
- profile,
- details,
- })
- } else {
- /* Send slack notification. */
- slack({
- _address,
- _cashAccounts,
- })
- }
- }
- /**
- * Projects
- */
- const projects = async function (req, res) {
- // console.log('REQUEST', req)
- /* Set id. */
- // const baseCurrency = req.params.baseCurrency
- // const quoteCurrency = req.params.quoteCurrency
- // const symbol = req.query.symbol
- // console.log('BASE CURRENCY', baseCurrency)
- // console.log('QUOTE CURRENCY', quoteCurrency)
- /* Set headers. */
- // const headers = req.headers
- // console.log('HEADERS', headers)
- /* Set body. */
- const body = req.body
- // console.log('\nBODY', body)
- /* Validate request body. */
- const validation = cashid.validateRequest(body)
- // console.log('\nVALIDATION', validation)
- /* Parse request. */
- // const parsed = cashid.parseCashIDRequest(body.request)
- // console.log('\nPARSED', parsed)
- // TODO: We MUST validate the timestamp to within 30 seconds
- // either before or after our server time (check clock)
- if (validation && validation.address) {
- // console.log('VALIDATION SUCCESS', validation.address, body.address)
- /* Set session id. */
- const sessionId = uuidv4()
- // console.log('SESSION ID', sessionId)
- /* Set address. */
- const address = validation.address
- // console.log('ADDRESS', address)
- /* Set signature. */
- const signature = validation.signature
- // console.log('SIGNATURE', signature)
- /* Set data. */
- const data = validation.data
- // console.log('DATA', data)
- /* Validate address. */
- if (address !== body.address) {
- return res.json({
- error: 'Address DOES NOT match.',
- statuscode: 131
- })
- }
- /* Validate signature. */
- if (signature !== body.signature) {
- return res.json({
- error: 'Signature DOES NOT match.',
- statuscode: 131
- })
- }
- /* Validate data. */
- if (data !== body.data) {
- return res.json({
- error: 'Data DOES NOT match.',
- statuscode: 131
- })
- }
- /* Set CashID buffer. */
- const cidBuf = Buffer.from(body.request)
- // console.log('CASHID REQUEST BUFFER', cidBuf)
- /* Set CashID (authorization) hash. */
- // const authHash = bitbox.Crypto.sha256(cidBuf).toString('hex')
- // console.log('CASHID AUTH HASH', authHash)
- /* Initialize cash account(s). */
- let cashAccounts = []
- // const reverseLookup = await bitbox.CashAccounts
- // .reverseLookup(address)
- // .catch(err => console.error('REVERSE LOOKUP ERROR:', err))
- // console.log('REVERSE LOOKUP', reverseLookup)
- /* Validate lookup. */
- if (reverseLookup && reverseLookup.results) {
- reverseLookup.results.forEach(account => {
- /* Add cash account info. */
- cashAccounts.push({
- accountEmoji: account.accountEmoji,
- nameText: account.nameText,
- accountNumber: account.accountNumber,
- })
- })
- }
- /* Add new profile. */
- addNewProfile(address, cashAccounts)
- /* Initialize response. */
- let response = null
- /* Set active flag. */
- const isActive = true
- /* Set creation date. */
- const createdAt = moment().valueOf()
- /* Set last update. */
- const updatedAt = moment().valueOf()
- try {
- response = await dbSessions.put({
- _id: sessionId,
- authHash,
- validation,
- cashAccounts,
- isActive,
- createdAt,
- updatedAt
- })
- console.log('DB RESPONSE', response)
- } catch (err) {
- console.log('DB ERROR:', err)
- }
- // FIXME: Perform more validation
- return res.json({
- statuscode: 0
- // 'status': 0
- })
- } else {
- console.log('VALIDATION FAILED!')
- // FIXME: Parse the actual status code
- // `Request domain api.apecs.dev is invalid, this service uses auth.cashid.org, statuscode:131`
- /* Set status code. */
- // res.status(131)
- return res.json({
- statuscode: 131
- // 'status': 1
- // 'status': 131
- })
- }
- }
- module.exports = projects
|