feat: changed old server ports so it can coexists with the new server

feat: removed deleted references from old server

feat: created reset and migrate mutations on gql server and
correspondent functions on new settings loader

feat: created front end for the config migration with reset and migrate
functionalities

style: add spacing between buttons
Signed-off-by: Liordino Neto <liordinoneto@gmail.com>
This commit is contained in:
Liordino Neto 2020-11-26 20:02:04 -03:00 committed by Josh Harvey
parent 368d528ee2
commit df8a1804a3
6 changed files with 144 additions and 65 deletions

View file

@ -31,7 +31,6 @@ const server = require('./server')
const transactions = require('./transactions') const transactions = require('./transactions')
const customers = require('../customers') const customers = require('../customers')
const logs = require('../logs') const logs = require('../logs')
const supportLogs = require('../support_logs')
const funding = require('./funding') const funding = require('./funding')
const supportServer = require('./admin-support') const supportServer = require('./admin-support')
@ -208,29 +207,6 @@ app.get('/api/logs', (req, res, next) => {
.catch(next) .catch(next)
}) })
app.get('/api/support_logs', (req, res, next) => {
return supportLogs.batch()
.then(supportLogs => res.send({ supportLogs }))
.catch(next)
})
app.get('/api/support_logs/logs', (req, res, next) => {
return supportLogs.get(req.query.supportLogId)
.then(log => (!_.isNil(log) && !_.isEmpty(log)) ? log : supportLogs.batch().then(_.first))
.then(result => {
const log = result || {}
return logs.getMachineLogs(log.deviceId, log.timestamp)
})
.then(r => res.send(r))
.catch(next)
})
app.post('/api/support_logs', (req, res, next) => {
return supportLogs.insert(req.query.deviceId)
.then(r => res.send(r))
.catch(next)
})
app.patch('/api/customer/:id', (req, res, next) => { app.patch('/api/customer/:id', (req, res, next) => {
if (!req.params.id) return res.status(400).send({Error: 'Requires id'}) if (!req.params.id) return res.status(400).send({Error: 'Requires id'})
const token = req.token || req.cookies.token const token = req.token || req.cookies.token
@ -349,7 +325,7 @@ wss.on('connection', ws => {
}) })
function run () { function run () {
const serverPort = devMode ? 8070 : 443 const serverPort = devMode ? 8072 : 443
const supportPort = 8071 const supportPort = 8071
const serverLog = `lamassu-admin-server listening on port ${serverPort}` const serverLog = `lamassu-admin-server listening on port ${serverPort}`

View file

@ -10,8 +10,6 @@ const _ = require('lodash/fp')
const serveStatic = require('serve-static') const serveStatic = require('serve-static')
const path = require('path') const path = require('path')
const logs = require('../logs')
const supportLogs = require('../support_logs')
const options = require('../options') const options = require('../options')
app.use(morgan('dev')) app.use(morgan('dev'))
@ -30,29 +28,6 @@ const certOptions = {
rejectUnauthorized: true rejectUnauthorized: true
} }
app.get('/api/support_logs', (req, res, next) => {
return supportLogs.batch()
.then(supportLogs => res.send({ supportLogs }))
.catch(next)
})
app.get('/api/support_logs/logs', (req, res, next) => {
return supportLogs.get(req.query.supportLogId)
.then(log => (!_.isNil(log) && !_.isEmpty(log)) ? log : supportLogs.batch().then(_.first))
.then(result => {
const log = result || {}
return logs.getUnlimitedMachineLogs(log.deviceId, log.timestamp)
})
.then(r => res.send(r))
.catch(next)
})
app.post('/api/support_logs', (req, res, next) => {
return supportLogs.insert(req.query.deviceId)
.then(r => res.send(r))
.catch(next)
})
function run (port) { function run (port) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const webServer = https.createServer(certOptions, app) const webServer = https.createServer(certOptions, app)

View file

@ -271,8 +271,11 @@ const typeDefs = gql`
machineAction(deviceId:ID!, action: MachineAction!, cassette1: Int, cassette2: Int, newName: String): Machine machineAction(deviceId:ID!, action: MachineAction!, cassette1: Int, cassette2: Int, newName: String): Machine
setCustomer(customerId: ID!, customerInput: CustomerInput): Customer setCustomer(customerId: ID!, customerInput: CustomerInput): Customer
saveConfig(config: JSONObject): JSONObject saveConfig(config: JSONObject): JSONObject
resetConfig(schemaVersion: Int): JSONObject
createPairingTotem(name: String!): String createPairingTotem(name: String!): String
saveAccounts(accounts: JSONObject): JSONObject saveAccounts(accounts: JSONObject): JSONObject
resetAccounts(schemaVersion: Int): JSONObject
migrateConfigAndAccounts: JSONObject
revokeToken(token: String!): UserToken revokeToken(token: String!): UserToken
deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist
insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist
@ -331,6 +334,7 @@ const resolvers = {
machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }), machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }),
createPairingTotem: (...[, { name }]) => pairing.totem(name), createPairingTotem: (...[, { name }]) => pairing.totem(name),
saveAccounts: (...[, { accounts }]) => settingsLoader.saveAccounts(accounts), saveAccounts: (...[, { accounts }]) => settingsLoader.saveAccounts(accounts),
resetAccounts: (...[, { schemaVersion }]) => settingsLoader.resetAccounts(schemaVersion),
setCustomer: (root, args, context, info) => { setCustomer: (root, args, context, info) => {
const token = context.req.cookies && context.req.cookies.token const token = context.req.cookies && context.req.cookies.token
return customers.updateCustomer(args.customerId, args.customerInput, token) return customers.updateCustomer(args.customerId, args.customerInput, token)
@ -340,6 +344,8 @@ const resolvers = {
notify() notify()
return it return it
}), }),
resetConfig: (...[, { schemaVersion }]) => settingsLoader.resetConfig(schemaVersion),
migrateConfigAndAccounts: () => settingsLoader.migrate(),
deleteBlacklistRow: (...[, { cryptoCode, address }]) => deleteBlacklistRow: (...[, { cryptoCode, address }]) =>
blacklist.deleteFromBlacklist(cryptoCode, address), blacklist.deleteFromBlacklist(cryptoCode, address),
insertBlacklistRow: (...[, { cryptoCode, address }]) => insertBlacklistRow: (...[, { cryptoCode, address }]) =>

View file

@ -1,21 +1,33 @@
const _ = require('lodash/fp') const _ = require('lodash/fp')
const db = require('./db') const db = require('./db')
const migration = require('./config-migration')
const OLD_SETTINGS_LOADER_SCHEMA_VERSION = 1
const NEW_SETTINGS_LOADER_SCHEMA_VERSION = 2 const NEW_SETTINGS_LOADER_SCHEMA_VERSION = 2
function saveAccounts (accountsToSave) { const accountsSql = `update user_config set data = $2, valid = $3, schema_version = $4 where type = $1;
const sql = `update user_config set data = $2, valid = $3, schema_version = $4 where type = $1;
insert into user_config (type, data, valid, schema_version) insert into user_config (type, data, valid, schema_version)
select $1, $2, $3, $4 where $1 not in (select type from user_config)` select $1, $2, $3, $4 where $1 not in (select type from user_config)`
function saveAccounts (accountsToSave) {
return loadAccounts() return loadAccounts()
.then(currentAccounts => { .then(currentAccounts => {
const newAccounts = _.assign(currentAccounts, accountsToSave) const newAccounts = _.assign(currentAccounts, accountsToSave)
return db.none(sql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION]) return db.none(accountsSql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
}) })
} }
function resetAccounts (schemaVersion) {
return db.none(
accountsSql,
[
'accounts',
{ accounts: NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },
true,
schemaVersion
]
)
}
function loadAccounts () { function loadAccounts (schemaVersion) {
const sql = `select data const sql = `select data
from user_config from user_config
where type=$1 where type=$1
@ -24,22 +36,34 @@ function loadAccounts () {
order by id desc order by id desc
limit 1` limit 1`
return db.oneOrNone(sql, ['accounts', NEW_SETTINGS_LOADER_SCHEMA_VERSION]) return db.oneOrNone(sql, ['accounts', schemaVersion || NEW_SETTINGS_LOADER_SCHEMA_VERSION])
.then(_.compose(_.defaultTo({}), _.get('data.accounts'))) .then(_.compose(_.defaultTo({}), _.get('data.accounts')))
} }
const configSql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)'
function saveConfig (config) { function saveConfig (config) {
const sql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)' console.log(config)
return loadLatestConfigOrNone() return loadLatestConfigOrNone()
.then(currentConfig => { .then(currentConfig => {
const newConfig = _.assign(currentConfig, config) const newConfig = _.assign(currentConfig, config)
return db.none(sql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION]) return db.none(configSql, ['config', { config: newConfig }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
}) })
} }
function loadLatest () { function resetConfig (schemaVersion) {
return Promise.all([loadLatestConfigOrNone(), loadAccounts()]) return db.none(
configSql,
[
'config',
{ config: schemaVersion === NEW_SETTINGS_LOADER_SCHEMA_VERSION ? {} : [] },
true,
schemaVersion
]
)
}
function loadLatest (schemaVersion) {
return Promise.all([loadLatestConfigOrNone(schemaVersion), loadAccounts(schemaVersion)])
.then(([config, accounts]) => ({ .then(([config, accounts]) => ({
config, config,
accounts accounts
@ -62,7 +86,7 @@ function loadLatestConfig () {
}) })
} }
function loadLatestConfigOrNone () { function loadLatestConfigOrNone (schemaVersion) {
const sql = `select data const sql = `select data
from user_config from user_config
where type=$1 where type=$1
@ -70,7 +94,7 @@ function loadLatestConfigOrNone () {
order by id desc order by id desc
limit 1` limit 1`
return db.oneOrNone(sql, ['config', NEW_SETTINGS_LOADER_SCHEMA_VERSION]) return db.oneOrNone(sql, ['config', schemaVersion || NEW_SETTINGS_LOADER_SCHEMA_VERSION])
.then(row => row ? row.data.config : {}) .then(row => row ? row.data.config : {})
} }
@ -103,12 +127,26 @@ function load (versionId) {
})) }))
} }
function migrate () {
return loadLatest(OLD_SETTINGS_LOADER_SCHEMA_VERSION)
.then(res => {
const migrated = migration.migrate(res.config, res.accounts)
saveConfig(migrated.config)
saveAccounts(migrated.accounts)
return migrated
})
}
module.exports = { module.exports = {
saveConfig, saveConfig,
resetConfig,
saveAccounts, saveAccounts,
resetAccounts,
loadAccounts, loadAccounts,
loadLatest, loadLatest,
loadLatestConfig, loadLatestConfig,
loadLatestConfigOrNone, loadLatestConfigOrNone,
load load,
migrate
} }

View file

@ -0,0 +1,82 @@
import { useMutation } from '@apollo/react-hooks'
import { Box } from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag'
import React, { useState } from 'react'
import Title from 'src/components/Title'
import { Button } from 'src/components/buttons'
const styles = {
button: {
marginBottom: 10
}
}
const useStyles = makeStyles(styles)
const RESET = gql`
mutation Reset($schemaVersion: Int) {
resetConfig(schemaVersion: $schemaVersion)
resetAccounts(schemaVersion: $schemaVersion)
}
`
const MIGRATE = gql`
mutation Migrate {
migrateConfigAndAccounts
}
`
const OLD_SCHEMA_VERSION = 1
const NEW_SCHEMA_VERSION = 2
const ConfigMigration = () => {
const [loading, setLoading] = useState(false)
const [reset] = useMutation(RESET, {
onCompleted: () => setLoading(false)
})
const [migrate] = useMutation(MIGRATE, {
onCompleted: () => setLoading(false)
})
const classes = useStyles()
const innerReset = schemaVersion => {
setLoading(true)
reset({ variables: { schemaVersion } })
}
const innerMigrate = () => {
setLoading(true)
migrate()
}
return (
<>
<Title>Config Migration</Title>
<Box display="flex" alignItems="center" flexDirection="column">
<Button
className={classes.button}
disabled={loading}
onClick={() => innerReset(OLD_SCHEMA_VERSION)}>
Reset old admin
</Button>
<Button
className={classes.button}
disabled={loading}
onClick={() => innerReset(NEW_SCHEMA_VERSION)}>
Reset new admin
</Button>
<Button
className={classes.button}
disabled={loading}
onClick={() => innerMigrate()}>
Migrate
</Button>
</Box>
</>
)
}
export default ConfigMigration

View file

@ -13,6 +13,7 @@ import AuthRegister from 'src/pages/AuthRegister'
import Blacklist from 'src/pages/Blacklist' import Blacklist from 'src/pages/Blacklist'
import Cashout from 'src/pages/Cashout' import Cashout from 'src/pages/Cashout'
import Commissions from 'src/pages/Commissions' import Commissions from 'src/pages/Commissions'
import ConfigMigration from 'src/pages/ConfigMigration'
import { Customers, CustomerProfile } from 'src/pages/Customers' import { Customers, CustomerProfile } from 'src/pages/Customers'
import Funding from 'src/pages/Funding' import Funding from 'src/pages/Funding'
import Locales from 'src/pages/Locales' import Locales from 'src/pages/Locales'
@ -259,6 +260,7 @@ const Routes = () => {
</Route> </Route>
<Route path="/wizard" component={Wizard} /> <Route path="/wizard" component={Wizard} />
<Route path="/register" component={AuthRegister} /> <Route path="/register" component={AuthRegister} />
<Route path="/configmigration" component={ConfigMigration} />
{flattened.map(({ route, component: Page, key }) => ( {flattened.map(({ route, component: Page, key }) => (
<Route path={route} key={key}> <Route path={route} key={key}>
<Page name={key} /> <Page name={key} />