diff --git a/lib/admin/admin-server.js b/lib/admin/admin-server.js index 317098c4..66273b51 100644 --- a/lib/admin/admin-server.js +++ b/lib/admin/admin-server.js @@ -31,7 +31,6 @@ const server = require('./server') const transactions = require('./transactions') const customers = require('../customers') const logs = require('../logs') -const supportLogs = require('../support_logs') const funding = require('./funding') const supportServer = require('./admin-support') @@ -208,29 +207,6 @@ app.get('/api/logs', (req, res, 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) => { if (!req.params.id) return res.status(400).send({Error: 'Requires id'}) const token = req.token || req.cookies.token @@ -349,7 +325,7 @@ wss.on('connection', ws => { }) function run () { - const serverPort = devMode ? 8070 : 443 + const serverPort = devMode ? 8072 : 443 const supportPort = 8071 const serverLog = `lamassu-admin-server listening on port ${serverPort}` diff --git a/lib/admin/admin-support.js b/lib/admin/admin-support.js index 85c9d250..753e160f 100644 --- a/lib/admin/admin-support.js +++ b/lib/admin/admin-support.js @@ -10,8 +10,6 @@ const _ = require('lodash/fp') const serveStatic = require('serve-static') const path = require('path') -const logs = require('../logs') -const supportLogs = require('../support_logs') const options = require('../options') app.use(morgan('dev')) @@ -30,29 +28,6 @@ const certOptions = { 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) { return new Promise((resolve, reject) => { const webServer = https.createServer(certOptions, app) diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js index 42da3110..45589700 100644 --- a/lib/new-admin/graphql/schema.js +++ b/lib/new-admin/graphql/schema.js @@ -271,8 +271,11 @@ const typeDefs = gql` machineAction(deviceId:ID!, action: MachineAction!, cassette1: Int, cassette2: Int, newName: String): Machine setCustomer(customerId: ID!, customerInput: CustomerInput): Customer saveConfig(config: JSONObject): JSONObject + resetConfig(schemaVersion: Int): JSONObject createPairingTotem(name: String!): String saveAccounts(accounts: JSONObject): JSONObject + resetAccounts(schemaVersion: Int): JSONObject + migrateConfigAndAccounts: JSONObject revokeToken(token: String!): UserToken deleteBlacklistRow(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 }), createPairingTotem: (...[, { name }]) => pairing.totem(name), saveAccounts: (...[, { accounts }]) => settingsLoader.saveAccounts(accounts), + resetAccounts: (...[, { schemaVersion }]) => settingsLoader.resetAccounts(schemaVersion), setCustomer: (root, args, context, info) => { const token = context.req.cookies && context.req.cookies.token return customers.updateCustomer(args.customerId, args.customerInput, token) @@ -340,6 +344,8 @@ const resolvers = { notify() return it }), + resetConfig: (...[, { schemaVersion }]) => settingsLoader.resetConfig(schemaVersion), + migrateConfigAndAccounts: () => settingsLoader.migrate(), deleteBlacklistRow: (...[, { cryptoCode, address }]) => blacklist.deleteFromBlacklist(cryptoCode, address), insertBlacklistRow: (...[, { cryptoCode, address }]) => diff --git a/lib/new-settings-loader.js b/lib/new-settings-loader.js index 88ca3231..ab435c18 100644 --- a/lib/new-settings-loader.js +++ b/lib/new-settings-loader.js @@ -1,21 +1,33 @@ const _ = require('lodash/fp') const db = require('./db') +const migration = require('./config-migration') +const OLD_SETTINGS_LOADER_SCHEMA_VERSION = 1 const NEW_SETTINGS_LOADER_SCHEMA_VERSION = 2 +const accountsSql = `update user_config set data = $2, valid = $3, schema_version = $4 where type = $1; +insert into user_config (type, data, valid, schema_version) +select $1, $2, $3, $4 where $1 not in (select type from user_config)` function saveAccounts (accountsToSave) { - 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) - select $1, $2, $3, $4 where $1 not in (select type from user_config)` - return loadAccounts() .then(currentAccounts => { 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 from user_config where type=$1 @@ -24,22 +36,34 @@ function loadAccounts () { order by id desc 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'))) } +const configSql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)' function saveConfig (config) { - const sql = 'insert into user_config (type, data, valid, schema_version) values ($1, $2, $3, $4)' - + console.log(config) return loadLatestConfigOrNone() .then(currentConfig => { 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 () { - return Promise.all([loadLatestConfigOrNone(), loadAccounts()]) +function resetConfig (schemaVersion) { + 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]) => ({ config, accounts @@ -62,7 +86,7 @@ function loadLatestConfig () { }) } -function loadLatestConfigOrNone () { +function loadLatestConfigOrNone (schemaVersion) { const sql = `select data from user_config where type=$1 @@ -70,7 +94,7 @@ function loadLatestConfigOrNone () { order by id desc 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 : {}) } @@ -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 = { saveConfig, + resetConfig, saveAccounts, + resetAccounts, loadAccounts, loadLatest, loadLatestConfig, loadLatestConfigOrNone, - load + load, + migrate } diff --git a/new-lamassu-admin/src/pages/ConfigMigration.js b/new-lamassu-admin/src/pages/ConfigMigration.js new file mode 100644 index 00000000..6da89560 --- /dev/null +++ b/new-lamassu-admin/src/pages/ConfigMigration.js @@ -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 ( + <> + Config Migration + + + + + + + ) +} + +export default ConfigMigration diff --git a/new-lamassu-admin/src/routing/routes.js b/new-lamassu-admin/src/routing/routes.js index de280ba2..d7f5b562 100644 --- a/new-lamassu-admin/src/routing/routes.js +++ b/new-lamassu-admin/src/routing/routes.js @@ -13,6 +13,7 @@ import AuthRegister from 'src/pages/AuthRegister' import Blacklist from 'src/pages/Blacklist' import Cashout from 'src/pages/Cashout' import Commissions from 'src/pages/Commissions' +import ConfigMigration from 'src/pages/ConfigMigration' import { Customers, CustomerProfile } from 'src/pages/Customers' import Funding from 'src/pages/Funding' import Locales from 'src/pages/Locales' @@ -259,6 +260,7 @@ const Routes = () => { + {flattened.map(({ route, component: Page, key }) => (