From 9fa97725ec20c80b5aa065a19f3b5a433d236d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Wed, 7 Apr 2021 16:11:06 +0100 Subject: [PATCH] feat: auto userdata fetch fix: gql directives and overall minor fixes --- lib/new-admin/admin-server.js | 3 - .../graphql/modules/authentication.js | 3 +- lib/new-admin/graphql/types/bill.type.js | 2 +- lib/new-admin/graphql/types/blacklist.type.js | 6 +- lib/new-admin/graphql/types/config.type.js | 6 +- lib/new-admin/graphql/types/currency.type.js | 4 +- lib/new-admin/graphql/types/customer.type.js | 6 +- lib/new-admin/graphql/types/funding.type.js | 2 +- lib/new-admin/graphql/types/log.type.js | 8 +- lib/new-admin/graphql/types/machine.type.js | 6 +- .../graphql/types/notification.type.js | 10 +-- lib/new-admin/graphql/types/pairing.type.js | 2 +- lib/new-admin/graphql/types/promo.type.js | 6 +- lib/new-admin/graphql/types/rates.type.js | 4 +- lib/new-admin/graphql/types/settings.type.js | 14 ++-- lib/new-admin/graphql/types/status.type.js | 2 +- .../graphql/types/transaction.type.js | 2 +- lib/new-admin/graphql/types/version.type.js | 2 +- lib/new-admin/routes/auth.js | 17 ----- lib/users.js | 14 +++- new-lamassu-admin/src/lamassu/App.js | 75 +++++++++---------- new-lamassu-admin/src/utils/apollo.js | 27 +------ 22 files changed, 94 insertions(+), 127 deletions(-) delete mode 100644 lib/new-admin/routes/auth.js diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js index af91b673..e28c0795 100644 --- a/lib/new-admin/admin-server.js +++ b/lib/new-admin/admin-server.js @@ -11,13 +11,11 @@ const cookieParser = require('cookie-parser') const bodyParser = require('body-parser') const { ApolloServer, AuthenticationError } = require('apollo-server-express') const _ = require('lodash/fp') -const pify = require('pify') const options = require('../options') const users = require('../users') const session = require('./middlewares/session') -const authRouter = require('./routes/auth') const { AuthDirective } = require('./graphql/directives') const { typeDefs, resolvers } = require('./graphql/schema') @@ -86,7 +84,6 @@ app.use(cors({ credentials: true, origin: devMode && 'https://localhost:3001' }) app.use('/id-card-photo', serveStatic(idPhotoCardBasedir, { index: false })) app.use('/front-camera-photo', serveStatic(frontCameraBasedir, { index: false })) -app.use(authRouter) // Everything not on graphql or api/register is redirected to the front-end app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'public', 'index.html'))) diff --git a/lib/new-admin/graphql/modules/authentication.js b/lib/new-admin/graphql/modules/authentication.js index 0ca3ed7a..f54ff0d9 100644 --- a/lib/new-admin/graphql/modules/authentication.js +++ b/lib/new-admin/graphql/modules/authentication.js @@ -1,5 +1,6 @@ const otplib = require('otplib') const bcrypt = require('bcrypt') +const { AuthenticationError } = require('apollo-server-express') const loginHelper = require('../../services/login') const T = require('../../../time') @@ -27,7 +28,7 @@ function authenticateUser(username, password) { const getUserData = context => { const lidCookie = context.req.cookies && context.req.cookies.lid - if (!lidCookie) throw new authErrors.InvalidCredentialsError() + if (!lidCookie) throw new AuthenticationError() const user = context.req.session.user return user diff --git a/lib/new-admin/graphql/types/bill.type.js b/lib/new-admin/graphql/types/bill.type.js index e7c4478a..67c1b87e 100644 --- a/lib/new-admin/graphql/types/bill.type.js +++ b/lib/new-admin/graphql/types/bill.type.js @@ -9,7 +9,7 @@ const typeDef = gql` } type Query { - bills: [Bill] + bills: [Bill] @auth } ` diff --git a/lib/new-admin/graphql/types/blacklist.type.js b/lib/new-admin/graphql/types/blacklist.type.js index 092c3012..08f2648f 100644 --- a/lib/new-admin/graphql/types/blacklist.type.js +++ b/lib/new-admin/graphql/types/blacklist.type.js @@ -8,12 +8,12 @@ const typeDef = gql` } type Query { - blacklist: [Blacklist] + blacklist: [Blacklist] @auth } type Mutation { - deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist - insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist + deleteBlacklistRow(cryptoCode: String!, address: String!): Blacklist @auth + insertBlacklistRow(cryptoCode: String!, address: String!): Blacklist @auth } ` diff --git a/lib/new-admin/graphql/types/config.type.js b/lib/new-admin/graphql/types/config.type.js index 952bfb43..be33cbf0 100644 --- a/lib/new-admin/graphql/types/config.type.js +++ b/lib/new-admin/graphql/types/config.type.js @@ -20,9 +20,9 @@ const typeDef = gql` } type Query { - countries: [Country] - languages: [Language] - accountsConfig: [AccountConfig] + countries: [Country] @auth + languages: [Language] @auth + accountsConfig: [AccountConfig] @auth } ` diff --git a/lib/new-admin/graphql/types/currency.type.js b/lib/new-admin/graphql/types/currency.type.js index 8bdfd7bf..ebfa91d8 100644 --- a/lib/new-admin/graphql/types/currency.type.js +++ b/lib/new-admin/graphql/types/currency.type.js @@ -12,8 +12,8 @@ const typeDef = gql` } type Query { - currencies: [Currency] - cryptoCurrencies: [CryptoCurrency] + currencies: [Currency] @auth + cryptoCurrencies: [CryptoCurrency] @auth } ` diff --git a/lib/new-admin/graphql/types/customer.type.js b/lib/new-admin/graphql/types/customer.type.js index 131ad7d6..0622c3cf 100644 --- a/lib/new-admin/graphql/types/customer.type.js +++ b/lib/new-admin/graphql/types/customer.type.js @@ -54,12 +54,12 @@ const typeDef = gql` } type Query { - customers: [Customer] - customer(customerId: ID!): Customer + customers: [Customer] @auth + customer(customerId: ID!): Customer @auth } type Mutation { - setCustomer(customerId: ID!, customerInput: CustomerInput): Customer + setCustomer(customerId: ID!, customerInput: CustomerInput): Customer @auth } ` diff --git a/lib/new-admin/graphql/types/funding.type.js b/lib/new-admin/graphql/types/funding.type.js index 8c9167b7..dcfa1cd7 100644 --- a/lib/new-admin/graphql/types/funding.type.js +++ b/lib/new-admin/graphql/types/funding.type.js @@ -16,7 +16,7 @@ const typeDef = gql` } type Query { - funding: [CoinFunds] + funding: [CoinFunds] @auth } ` diff --git a/lib/new-admin/graphql/types/log.type.js b/lib/new-admin/graphql/types/log.type.js index 4d10259a..166cbfde 100644 --- a/lib/new-admin/graphql/types/log.type.js +++ b/lib/new-admin/graphql/types/log.type.js @@ -16,10 +16,10 @@ const typeDef = gql` } type Query { - machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] - machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): String - serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] - serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int): String + machineLogs(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): [MachineLog] @auth + machineLogsCsv(deviceId: ID!, from: Date, until: Date, limit: Int, offset: Int): String @auth + serverLogs(from: Date, until: Date, limit: Int, offset: Int): [ServerLog] @auth + serverLogsCsv(from: Date, until: Date, limit: Int, offset: Int): String @auth } ` diff --git a/lib/new-admin/graphql/types/machine.type.js b/lib/new-admin/graphql/types/machine.type.js index d9da22d8..5fb80dab 100644 --- a/lib/new-admin/graphql/types/machine.type.js +++ b/lib/new-admin/graphql/types/machine.type.js @@ -43,12 +43,12 @@ const typeDef = gql` } type Query { - machines: [Machine] - machine(deviceId: ID!): Machine + machines: [Machine] @auth + machine(deviceId: ID!): Machine @auth } type Mutation { - machineAction(deviceId:ID!, action: MachineAction!, cashbox: Int, cassette1: Int, cassette2: Int, newName: String): Machine + machineAction(deviceId:ID!, action: MachineAction!, cashbox: Int, cassette1: Int, cassette2: Int, newName: String): Machine @auth } ` diff --git a/lib/new-admin/graphql/types/notification.type.js b/lib/new-admin/graphql/types/notification.type.js index 87c16bbb..5368ff60 100644 --- a/lib/new-admin/graphql/types/notification.type.js +++ b/lib/new-admin/graphql/types/notification.type.js @@ -12,14 +12,14 @@ const typeDef = gql` } type Query { - notifications: [Notification] - alerts: [Notification] - hasUnreadNotifications: Boolean + notifications: [Notification] @auth + alerts: [Notification] @auth + hasUnreadNotifications: Boolean @auth } type Mutation { - toggleClearNotification(id: ID!, read: Boolean!): Notification - clearAllNotifications: Notification + toggleClearNotification(id: ID!, read: Boolean!): Notification @auth + clearAllNotifications: Notification @auth } ` diff --git a/lib/new-admin/graphql/types/pairing.type.js b/lib/new-admin/graphql/types/pairing.type.js index f835fd4d..c08c79b0 100644 --- a/lib/new-admin/graphql/types/pairing.type.js +++ b/lib/new-admin/graphql/types/pairing.type.js @@ -2,7 +2,7 @@ const { gql } = require('apollo-server-express') const typeDef = gql` type Mutation { - createPairingTotem(name: String!): String + createPairingTotem(name: String!): String @auth } ` diff --git a/lib/new-admin/graphql/types/promo.type.js b/lib/new-admin/graphql/types/promo.type.js index bcfb5e6d..2c9fb3be 100644 --- a/lib/new-admin/graphql/types/promo.type.js +++ b/lib/new-admin/graphql/types/promo.type.js @@ -8,12 +8,12 @@ const typeDef = gql` } type Query { - promoCodes: [PromoCode] + promoCodes: [PromoCode] @auth } type Mutation { - createPromoCode(code: String!, discount: Int!): PromoCode - deletePromoCode(codeId: ID!): PromoCode + createPromoCode(code: String!, discount: Int!): PromoCode @auth + deletePromoCode(codeId: ID!): PromoCode @auth } ` diff --git a/lib/new-admin/graphql/types/rates.type.js b/lib/new-admin/graphql/types/rates.type.js index 6bee296f..abaf84dc 100644 --- a/lib/new-admin/graphql/types/rates.type.js +++ b/lib/new-admin/graphql/types/rates.type.js @@ -8,8 +8,8 @@ const typeDef = gql` } type Query { - cryptoRates: JSONObject - fiatRates: [Rate] + cryptoRates: JSONObject @auth + fiatRates: [Rate] @auth } ` diff --git a/lib/new-admin/graphql/types/settings.type.js b/lib/new-admin/graphql/types/settings.type.js index acfbcb70..3385a585 100644 --- a/lib/new-admin/graphql/types/settings.type.js +++ b/lib/new-admin/graphql/types/settings.type.js @@ -2,16 +2,16 @@ const { gql } = require('apollo-server-express') const typeDef = gql` type Query { - accounts: JSONObject - config: JSONObject + accounts: JSONObject @auth + config: JSONObject @auth } type Mutation { - saveAccounts(accounts: JSONObject): JSONObject - # resetAccounts(schemaVersion: Int): JSONObject - saveConfig(config: JSONObject): JSONObject - # resetConfig(schemaVersion: Int): JSONObject - # migrateConfigAndAccounts: JSONObject + saveAccounts(accounts: JSONObject): JSONObject @auth + # resetAccounts(schemaVersion: Int): JSONObject @auth + saveConfig(config: JSONObject): JSONObject @auth + # resetConfig(schemaVersion: Int): JSONObject @auth + # migrateConfigAndAccounts: JSONObject @auth } ` diff --git a/lib/new-admin/graphql/types/status.type.js b/lib/new-admin/graphql/types/status.type.js index 6af3546d..696b67f2 100644 --- a/lib/new-admin/graphql/types/status.type.js +++ b/lib/new-admin/graphql/types/status.type.js @@ -8,7 +8,7 @@ const typeDef = gql` } type Query { - uptime: [ProcessStatus] + uptime: [ProcessStatus] @auth } ` diff --git a/lib/new-admin/graphql/types/transaction.type.js b/lib/new-admin/graphql/types/transaction.type.js index 19c1f6cb..a4a553f9 100644 --- a/lib/new-admin/graphql/types/transaction.type.js +++ b/lib/new-admin/graphql/types/transaction.type.js @@ -46,7 +46,7 @@ const typeDef = gql` } type Query { - transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID): [Transaction] + transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID): [Transaction] @auth transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String } ` diff --git a/lib/new-admin/graphql/types/version.type.js b/lib/new-admin/graphql/types/version.type.js index 67a86d63..c57c29b9 100644 --- a/lib/new-admin/graphql/types/version.type.js +++ b/lib/new-admin/graphql/types/version.type.js @@ -2,7 +2,7 @@ const { gql } = require('apollo-server-express') const typeDef = gql` type Query { - serverVersion: String! + serverVersion: String! @auth } ` diff --git a/lib/new-admin/routes/auth.js b/lib/new-admin/routes/auth.js deleted file mode 100644 index 1df1a983..00000000 --- a/lib/new-admin/routes/auth.js +++ /dev/null @@ -1,17 +0,0 @@ -const express = require('express') -const router = express.Router() - -const getUserData = function (req, res, next) { - const lidCookie = req.cookies && req.cookies.lid - if (!lidCookie) { - res.sendStatus(403) - return - } - - const user = req.session.user - return res.status(200).json({ message: 'Success', user: user }) -} - -router.get('/user-data', getUserData) - -module.exports = router diff --git a/lib/users.js b/lib/users.js index 398be91e..bd323027 100644 --- a/lib/users.js +++ b/lib/users.js @@ -162,13 +162,19 @@ function changeUserRole (id, newRole) { } function enableUser (id) { - const sql = `UPDATE users SET enabled=true WHERE id=$1` - return db.none(sql, [id]) + return db.tx(t => { + const q1 = t.none(`UPDATE users SET enabled=true WHERE id=$1`, [id]) + const q2 = t.none(`DELETE FROM user_sessions WHERE sess -> 'user' ->> 'id'=$1`, [id]) + return t.batch([q1, q2]) + }) } function disableUser (id) { - const sql = `UPDATE users SET enabled=false WHERE id=$1` - return db.none(sql, [id]) + return db.tx(t => { + const q1 = t.none(`UPDATE users SET enabled=false WHERE id=$1`, [id]) + const q2 = t.none(`DELETE FROM user_sessions WHERE sess -> 'user' ->> 'id'=$1`, [id]) + return t.batch([q1, q2]) + }) } module.exports = { diff --git a/new-lamassu-admin/src/lamassu/App.js b/new-lamassu-admin/src/lamassu/App.js index 9ac13377..415314d5 100644 --- a/new-lamassu-admin/src/lamassu/App.js +++ b/new-lamassu-admin/src/lamassu/App.js @@ -1,3 +1,4 @@ +import { useQuery } from '@apollo/react-hooks' import CssBaseline from '@material-ui/core/CssBaseline' import Grid from '@material-ui/core/Grid' import { @@ -6,10 +7,11 @@ import { MuiThemeProvider, makeStyles } from '@material-ui/core/styles' -import { axios } from '@use-hooks/axios' +import gql from 'graphql-tag' import { create } from 'jss' import extendJss from 'jss-plugin-extend' -import React, { useContext, useEffect, useState } from 'react' +import * as R from 'ramda' +import React, { useContext, useState, useEffect } from 'react' import { useLocation, useHistory, @@ -73,7 +75,28 @@ const Main = () => { const classes = useStyles() const location = useLocation() const history = useHistory() - const { wizardTested, userData } = useContext(AppContext) + const { wizardTested, userData, setUserData } = useContext(AppContext) + + const GET_USER_DATA = gql` + query userData { + userData { + id + username + role + enabled + last_accessed + last_accessed_from + last_accessed_address + } + } + ` + + const { data: userResponse, loading } = useQuery(GET_USER_DATA) + + useEffect(() => { + if (!R.equals(userData, userResponse?.userData) && !loading) + setUserData(userResponse?.userData) + }, [loading, setUserData, userData, userResponse]) const route = location.pathname @@ -109,9 +132,7 @@ const Main = () => { onClick={onClick} /> )} -
- -
+
{!loading && }
@@ -121,42 +142,20 @@ const Main = () => { const App = () => { const [wizardTested, setWizardTested] = useState(false) const [userData, setUserData] = useState(null) - const [loading, setLoading] = useState(true) - - const url = - process.env.NODE_ENV === 'development' ? 'https://localhost:8070' : '' - - useEffect(() => { - axios({ - method: 'GET', - url: `${url}/user-data`, - withCredentials: true - }) - .then(res => { - setLoading(false) - if (res.status === 200) setUserData(res.data.user) - }) - .catch(err => { - setLoading(false) - if (err.status === 403) setUserData(null) - }) - }, [url]) return ( - {!loading && ( - - - - - -
- - - - - )} + + + + + +
+ + + + ) } diff --git a/new-lamassu-admin/src/utils/apollo.js b/new-lamassu-admin/src/utils/apollo.js index d402d8e9..0a2b58f3 100644 --- a/new-lamassu-admin/src/utils/apollo.js +++ b/new-lamassu-admin/src/utils/apollo.js @@ -4,7 +4,6 @@ import { ApolloClient } from 'apollo-client' import { ApolloLink } from 'apollo-link' import { onError } from 'apollo-link-error' import { HttpLink } from 'apollo-link-http' -import * as R from 'ramda' import React, { useContext } from 'react' import { useHistory, useLocation } from 'react-router-dom' @@ -19,12 +18,10 @@ const getClient = (history, location, setUserData) => onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) graphQLErrors.forEach(({ message, locations, path, extensions }) => { - handle( - { message, locations, path, extensions }, - history, - location, - setUserData - ) + if (extensions?.code === 'UNAUTHENTICATED') { + setUserData(null) + if (location.pathname !== '/login') history.push('/login') + } console.log( `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}` ) @@ -52,22 +49,6 @@ const getClient = (history, location, setUserData) => } }) -const handle = (apolloError, ...args) => { - const handler = { - UNAUTHENTICATED: (...args) => { - const history = args[0] - const location = args[1] - const setUserData = args[2] - setUserData(null) - if (location.pathname !== '/login') history.push('/login') - } - } - - if (!R.has(apolloError.extensions?.code, handler)) return apolloError - - return handler[apolloError.extensions?.code](...args) -} - const Provider = ({ children }) => { const history = useHistory() const location = useLocation()