refactor: user agent parsing
This commit is contained in:
parent
791b275cdf
commit
839e6aae47
8 changed files with 21 additions and 63 deletions
|
|
@ -68,10 +68,12 @@ app.use('/front-camera-photo', serveStatic(frontCameraBasedir, { index: false })
|
|||
|
||||
app.get('/api/register', (req, res, next) => {
|
||||
const otp = req.query.otp
|
||||
const ua = req.headers['user-agent']
|
||||
const ip = req.ip
|
||||
|
||||
if (!otp) return next()
|
||||
|
||||
return login.register(req)
|
||||
return login.register(otp, ua, ip)
|
||||
.then(r => {
|
||||
if (r.expired) return res.status(401).send('OTP expired, generate new registration link')
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ const typeDefs = gql`
|
|||
token: String!
|
||||
name: String!
|
||||
created: Date!
|
||||
user_agent: String!
|
||||
ip_address: String!
|
||||
}
|
||||
|
||||
type Transaction {
|
||||
|
|
@ -224,7 +226,7 @@ const typeDefs = gql`
|
|||
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int): String
|
||||
accounts: JSONObject
|
||||
config: JSONObject
|
||||
userTokens(browser: String!, os: String!): [UserToken]
|
||||
userTokens: [UserToken]
|
||||
}
|
||||
|
||||
enum MachineAction {
|
||||
|
|
@ -283,7 +285,7 @@ const resolvers = {
|
|||
transactions.batch(from, until, limit, offset).then(parseAsync),
|
||||
config: () => settingsLoader.loadLatestConfigOrNone(),
|
||||
accounts: () => settingsLoader.loadAccounts(),
|
||||
userTokens: (...[, { browser, os }]) => tokenManager.getTokenList(browser, os)
|
||||
userTokens: () => tokenManager.getTokenList()
|
||||
},
|
||||
Mutation: {
|
||||
machineAction: (...[, { deviceId, action, cassette1, cassette2, newName }]) => machineAction({ deviceId, action, cassette1, cassette2, newName }),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
const crypto = require('crypto')
|
||||
|
||||
const browserOS = require('../../new-lamassu-admin/src/utils/browser-os')
|
||||
const db = require('../db')
|
||||
|
||||
function generateOTP (name) {
|
||||
|
|
@ -22,18 +21,15 @@ function validateOTP (otp) {
|
|||
.catch(() => ({ success: false, expired: false }))
|
||||
}
|
||||
|
||||
function register (req) {
|
||||
const otp = req.query.otp
|
||||
|
||||
function register (otp, ua, ip) {
|
||||
return validateOTP(otp)
|
||||
.then(r => {
|
||||
if (!r.success) return r
|
||||
|
||||
const deviceInfo = browserOS.getInformation(req.headers['user-agent'])
|
||||
const token = crypto.randomBytes(32).toString('hex')
|
||||
const sql = 'insert into user_tokens (token, name, browser_version, os_version, ip_address) values ($1, $2, $3, $4, $5)'
|
||||
const sql = 'insert into user_tokens (token, name, user_agent, ip_address) values ($1, $2, $3, $4)'
|
||||
|
||||
return db.none(sql, [token, r.name, deviceInfo.browser, deviceInfo.OS, browserOS.getRequestIP(req)])
|
||||
return db.none(sql, [token, r.name, ua, ip])
|
||||
.then(() => ({ success: true, token: token }))
|
||||
})
|
||||
.catch(() => ({ success: false, expired: false }))
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
const db = require('./db')
|
||||
|
||||
function getTokenList (browser, os) {
|
||||
const sql = `select * from user_tokens where browser_version=$1 and os_version=$2`
|
||||
return db.any(sql, [browser, os])
|
||||
function getTokenList () {
|
||||
const sql = `select * from user_tokens`
|
||||
return db.any(sql)
|
||||
}
|
||||
|
||||
function revokeToken (token) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ 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 user_agent text',
|
||||
'ALTER TABLE user_tokens ADD COLUMN ip_address inet',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
import { useQuery, useMutation } from '@apollo/react-hooks'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import gql from 'graphql-tag'
|
||||
import moment from 'moment'
|
||||
import * as R from 'ramda'
|
||||
import React from 'react'
|
||||
|
||||
import Title from 'src/components/Title'
|
||||
import { IconButton } from 'src/components/buttons'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import DataTable from 'src/components/tables/DataTable'
|
||||
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'
|
||||
|
||||
const useStyles = makeStyles(mainStyles)
|
||||
|
||||
const GET_USER_TOKENS = gql`
|
||||
query userTokens($browser: String!, $os: String!) {
|
||||
userTokens(browser: $browser, os: $os) {
|
||||
query userTokens {
|
||||
userTokens {
|
||||
token
|
||||
name
|
||||
created
|
||||
user_agent
|
||||
ip_address
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
@ -34,16 +30,7 @@ const REVOKE_USER_TOKEN = gql`
|
|||
`
|
||||
|
||||
const Tokens = () => {
|
||||
const classes = useStyles()
|
||||
|
||||
const userAgent = browserOS.getInformation(navigator.userAgent)
|
||||
|
||||
const { data: tknResponse } = useQuery(GET_USER_TOKENS, {
|
||||
variables: {
|
||||
browser: `${userAgent.browser}`,
|
||||
os: `${userAgent.OS}`
|
||||
}
|
||||
})
|
||||
const { data: tknResponse } = useQuery(GET_USER_TOKENS)
|
||||
|
||||
const [revokeToken] = useMutation(REVOKE_USER_TOKEN, {
|
||||
refetchQueries: () => ['userTokens']
|
||||
|
|
@ -96,11 +83,7 @@ const Tokens = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.titleWrapper}>
|
||||
<div className={classes.titleAndButtonsContainer}>
|
||||
<Title>Token Management</Title>
|
||||
</div>
|
||||
</div>
|
||||
<TitleSection title="Token Management" />
|
||||
<DataTable
|
||||
elements={elements}
|
||||
data={R.path(['userTokens'])(tknResponse)}
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
import baseStyles from 'src/pages/Logs.styles'
|
||||
|
||||
const { titleWrapper, titleAndButtonsContainer } = baseStyles
|
||||
|
||||
const mainStyles = {
|
||||
titleWrapper,
|
||||
titleAndButtonsContainer
|
||||
}
|
||||
|
||||
export { mainStyles }
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
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 }
|
||||
Loading…
Add table
Add a link
Reference in a new issue