feat: add request data to user_tokens and token filtering
This commit is contained in:
parent
c4e7547c45
commit
791b275cdf
9 changed files with 61 additions and 16 deletions
|
|
@ -71,7 +71,7 @@ app.get('/api/register', (req, res, next) => {
|
||||||
|
|
||||||
if (!otp) return next()
|
if (!otp) return next()
|
||||||
|
|
||||||
return login.register(otp)
|
return login.register(req)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (r.expired) return res.status(401).send('OTP expired, generate new registration link')
|
if (r.expired) return res.status(401).send('OTP expired, generate new registration link')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ const typeDefs = gql`
|
||||||
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String
|
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String
|
||||||
accounts: JSONObject
|
accounts: JSONObject
|
||||||
config: JSONObject
|
config: JSONObject
|
||||||
userTokens: [UserToken]
|
userTokens(browser: String!, os: String!): [UserToken]
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MachineAction {
|
enum MachineAction {
|
||||||
|
|
@ -283,7 +283,7 @@ const resolvers = {
|
||||||
transactions.batch(from, until, limit, offset).then(parseAsync),
|
transactions.batch(from, until, limit, offset).then(parseAsync),
|
||||||
config: () => settingsLoader.loadLatestConfigOrNone(),
|
config: () => settingsLoader.loadLatestConfigOrNone(),
|
||||||
accounts: () => settingsLoader.loadAccounts(),
|
accounts: () => settingsLoader.loadAccounts(),
|
||||||
userTokens: () => tokenManager.getTokenList()
|
userTokens: (...[, { browser, os }]) => tokenManager.getTokenList(browser, os)
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }),
|
machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
|
|
||||||
|
const browserOS = require('../../new-lamassu-admin/src/utils/browser-os')
|
||||||
const db = require('../db')
|
const db = require('../db')
|
||||||
|
|
||||||
function generateOTP (name) {
|
function generateOTP (name) {
|
||||||
|
|
@ -21,15 +22,18 @@ function validateOTP (otp) {
|
||||||
.catch(() => ({ success: false, expired: false }))
|
.catch(() => ({ success: false, expired: false }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function register (otp) {
|
function register (req) {
|
||||||
|
const otp = req.query.otp
|
||||||
|
|
||||||
return validateOTP(otp)
|
return validateOTP(otp)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (!r.success) return r
|
if (!r.success) return r
|
||||||
|
|
||||||
|
const deviceInfo = browserOS.getInformation(req.headers['user-agent'])
|
||||||
const token = crypto.randomBytes(32).toString('hex')
|
const token = crypto.randomBytes(32).toString('hex')
|
||||||
const sql = 'insert into user_tokens (token, name) values ($1, $2)'
|
const sql = 'insert into user_tokens (token, name, browser_version, os_version, ip_address) values ($1, $2, $3, $4, $5)'
|
||||||
|
|
||||||
return db.none(sql, [token, r.name])
|
return db.none(sql, [token, r.name, deviceInfo.browser, deviceInfo.OS, browserOS.getRequestIP(req)])
|
||||||
.then(() => ({ success: true, token: token }))
|
.then(() => ({ success: true, token: token }))
|
||||||
})
|
})
|
||||||
.catch(() => ({ success: false, expired: false }))
|
.catch(() => ({ success: false, expired: false }))
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const db = require('./db')
|
const db = require('./db')
|
||||||
|
|
||||||
function getTokenList () {
|
function getTokenList (browser, os) {
|
||||||
const sql = `select * from user_tokens`
|
const sql = `select * from user_tokens where browser_version=$1 and os_version=$2`
|
||||||
return db.any(sql)
|
return db.any(sql, [browser, os])
|
||||||
}
|
}
|
||||||
|
|
||||||
function revokeToken (token) {
|
function revokeToken (token) {
|
||||||
|
|
@ -10,4 +10,4 @@ function revokeToken (token) {
|
||||||
return db.none(sql, [token])
|
return db.none(sql, [token])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getTokenList, revokeToken }
|
module.exports = { getTokenList, revokeToken }
|
||||||
|
|
|
||||||
15
migrations/1603438527057-add-browser-os-info.js
Normal file
15
migrations/1603438527057-add-browser-os-info.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
const db = require('./db')
|
||||||
|
|
||||||
|
exports.up = function (next) {
|
||||||
|
var sql = [
|
||||||
|
'ALTER TABLE user_tokens ADD COLUMN browser_version text',
|
||||||
|
'ALTER TABLE user_tokens ADD COLUMN os_version text',
|
||||||
|
'ALTER TABLE user_tokens ADD COLUMN ip_address inet',
|
||||||
|
]
|
||||||
|
|
||||||
|
db.multi(sql, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.down = function (next) {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|
@ -9,14 +9,15 @@ import Title from 'src/components/Title'
|
||||||
import { IconButton } from 'src/components/buttons'
|
import { IconButton } from 'src/components/buttons'
|
||||||
import DataTable from 'src/components/tables/DataTable'
|
import DataTable from 'src/components/tables/DataTable'
|
||||||
import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'
|
import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'
|
||||||
|
import * as browserOS from 'src/utils/browser-os'
|
||||||
|
|
||||||
import { mainStyles } from './TokenManagement.styles'
|
import { mainStyles } from './TokenManagement.styles'
|
||||||
|
|
||||||
const useStyles = makeStyles(mainStyles)
|
const useStyles = makeStyles(mainStyles)
|
||||||
|
|
||||||
const GET_USER_TOKENS = gql`
|
const GET_USER_TOKENS = gql`
|
||||||
query userTokens {
|
query userTokens($browser: String!, $os: String!) {
|
||||||
userTokens {
|
userTokens(browser: $browser, os: $os) {
|
||||||
token
|
token
|
||||||
name
|
name
|
||||||
created
|
created
|
||||||
|
|
@ -35,11 +36,16 @@ const REVOKE_USER_TOKEN = gql`
|
||||||
const Tokens = () => {
|
const Tokens = () => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
|
|
||||||
const { data: tknResponse } = useQuery(GET_USER_TOKENS)
|
const userAgent = browserOS.getInformation(navigator.userAgent)
|
||||||
|
|
||||||
|
const { data: tknResponse } = useQuery(GET_USER_TOKENS, {
|
||||||
|
variables: {
|
||||||
|
browser: `${userAgent.browser}`,
|
||||||
|
os: `${userAgent.OS}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const [revokeToken] = useMutation(REVOKE_USER_TOKEN, {
|
const [revokeToken] = useMutation(REVOKE_USER_TOKEN, {
|
||||||
onCompleted: () => console.log('passed'),
|
|
||||||
onError: () => console.log('failed'),
|
|
||||||
refetchQueries: () => ['userTokens']
|
refetchQueries: () => ['userTokens']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
14
new-lamassu-admin/src/utils/browser-os.js
Normal file
14
new-lamassu-admin/src/utils/browser-os.js
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
const parser = require('ua-parser-js')
|
||||||
|
|
||||||
|
function getRequestIP(req) {
|
||||||
|
return req.ip
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInformation(uaString) {
|
||||||
|
const userAgent = parser(uaString)
|
||||||
|
const browser = `${userAgent.browser.name} ${userAgent.browser.version}`
|
||||||
|
const OS = `${userAgent.os.name} ${userAgent.os.version}`
|
||||||
|
return { browser: browser, OS: OS }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getRequestIP, getInformation }
|
||||||
7
package-lock.json
generated
7
package-lock.json
generated
|
|
@ -10541,6 +10541,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
||||||
"integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
|
"integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
|
||||||
},
|
},
|
||||||
|
"ua-parser-js": {
|
||||||
|
"version": "0.7.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz",
|
||||||
|
"integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q=="
|
||||||
|
},
|
||||||
"ultron": {
|
"ultron": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||||
|
|
@ -10795,7 +10800,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/web3/-/web3-0.20.7.tgz",
|
"resolved": "https://registry.npmjs.org/web3/-/web3-0.20.7.tgz",
|
||||||
"integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==",
|
"integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git",
|
"bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934",
|
||||||
"crypto-js": "^3.1.4",
|
"crypto-js": "^3.1.4",
|
||||||
"utf8": "^2.1.1",
|
"utf8": "^2.1.1",
|
||||||
"xhr2-cookies": "^1.1.0",
|
"xhr2-cookies": "^1.1.0",
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
"socket.io-client": "^2.0.3",
|
"socket.io-client": "^2.0.3",
|
||||||
"talisman": "^0.20.0",
|
"talisman": "^0.20.0",
|
||||||
"twilio": "^3.6.1",
|
"twilio": "^3.6.1",
|
||||||
|
"ua-parser-js": "^0.7.22",
|
||||||
"uuid": "^3.1.0",
|
"uuid": "^3.1.0",
|
||||||
"web3": "^0.20.6",
|
"web3": "^0.20.6",
|
||||||
"winston": "^2.4.2",
|
"winston": "^2.4.2",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue