feat: add revoke token button

This commit is contained in:
Sérgio Salgado 2020-10-22 11:24:00 +01:00 committed by Josh Harvey
parent 4b44e1ef97
commit c4e7547c45
4 changed files with 58 additions and 65 deletions

View file

@ -243,6 +243,7 @@ const typeDefs = gql`
saveConfig(config: JSONObject): JSONObject saveConfig(config: JSONObject): JSONObject
createPairingTotem(name: String!): String createPairingTotem(name: String!): String
saveAccounts(accounts: JSONObject): JSONObject saveAccounts(accounts: JSONObject): JSONObject
revokeToken(token: String!): UserToken
} }
` `
@ -293,7 +294,8 @@ const resolvers = {
.then(it => { .then(it => {
notify() notify()
return it return it
}) }),
revokeToken: (...[, { token }]) => tokenManager.revokeToken(token)
} }
} }

View file

@ -1,8 +1,13 @@
const db = require('./db') const db = require('./db')
function getTokenList() { function getTokenList () {
const sql = `select * from user_tokens` const sql = `select * from user_tokens`
return db.any(sql); return db.any(sql)
} }
module.exports = { getTokenList } function revokeToken (token) {
const sql = `delete from user_tokens where token = $1`
return db.none(sql, [token])
}
module.exports = { getTokenList, revokeToken }

View file

@ -1,4 +1,4 @@
import { useQuery } from '@apollo/react-hooks' import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import moment from 'moment' import moment from 'moment'
@ -6,15 +6,16 @@ import * as R from 'ramda'
import React from 'react' import React from 'react'
import Title from 'src/components/Title' import Title from 'src/components/Title'
// import DataTable from 'src/components/tables/DataTable' import { IconButton } from 'src/components/buttons'
import { Table as EditableTable } from 'src/components/editableTable' import DataTable from 'src/components/tables/DataTable'
import { ReactComponent as DeleteIcon } from 'src/styling/icons/action/delete/enabled.svg'
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 {
userTokens { userTokens {
token token
name name
@ -23,64 +24,72 @@ const GET_USER_TOKENS = gql`
} }
` `
const REVOKE_USER_TOKEN = gql`
mutation revokeToken($token: String!) {
revokeToken(token: $token) {
token
}
}
`
const Tokens = () => { const Tokens = () => {
const classes = useStyles() const classes = useStyles()
const { data: tknResponse } = useQuery(GET_USER_TOKENS) const { data: tknResponse } = useQuery(GET_USER_TOKENS)
const [revokeToken] = useMutation(REVOKE_USER_TOKEN, {
onCompleted: () => console.log('passed'),
onError: () => console.log('failed'),
refetchQueries: () => ['userTokens']
})
const elements = [ const elements = [
{ {
name: 'name',
header: 'Name', header: 'Name',
width: 312, width: 257,
textAlign: 'center', textAlign: 'center',
size: 'sm' size: 'sm',
view: t => t.name
}, },
{ {
name: 'token',
header: 'Token', header: 'Token',
width: 520, width: 505,
textAlign: 'center', textAlign: 'center',
size: 'sm' size: 'sm',
view: t => t.token
}, },
{ {
name: 'created',
header: 'Date (UTC)', header: 'Date (UTC)',
width: 140, width: 145,
textAlign: 'right', textAlign: 'right',
size: 'sm', size: 'sm',
view: t => moment.utc(t).format('YYYY-MM-DD') view: t => moment.utc(t.created).format('YYYY-MM-DD')
}, },
{ {
name: 'created',
header: 'Time (UTC)', header: 'Time (UTC)',
width: 140, width: 145,
textAlign: 'right', textAlign: 'right',
size: 'sm', size: 'sm',
view: t => moment.utc(t).format('HH:mm:ss') view: t => moment.utc(t.created).format('HH:mm:ss')
},
{
header: '',
width: 80,
textAlign: 'center',
size: 'sm',
view: t => (
<IconButton
onClick={() => {
revokeToken({ variables: { token: t.token } })
}}>
<DeleteIcon />
</IconButton>
)
} }
] ]
return ( return (
<> <>
{console.log(tknResponse)}
<div className={classes.titleWrapper}>
<div className={classes.titleAndButtonsContainer}>
<Title>Token Management</Title>
</div>
</div>
<EditableTable
name="tokenList"
elements={elements}
data={R.path(['userTokens'])(tknResponse)}
enableDelete
/>
</>
)
/* return (
<>
{console.log(tknResponse)}
<div className={classes.titleWrapper}> <div className={classes.titleWrapper}>
<div className={classes.titleAndButtonsContainer}> <div className={classes.titleAndButtonsContainer}>
<Title>Token Management</Title> <Title>Token Management</Title>
@ -91,7 +100,7 @@ const Tokens = () => {
data={R.path(['userTokens'])(tknResponse)} data={R.path(['userTokens'])(tknResponse)}
/> />
</> </>
) */ )
} }
export default Tokens export default Tokens

View file

@ -1,33 +1,10 @@
import typographyStyles from 'src/components/typography/styles'
import baseStyles from 'src/pages/Logs.styles' import baseStyles from 'src/pages/Logs.styles'
const { label1 } = typographyStyles const { titleWrapper, titleAndButtonsContainer } = baseStyles
const { titleWrapper, titleAndButtonsContainer, buttonsWrapper } = baseStyles
const mainStyles = { const mainStyles = {
titleWrapper, titleWrapper,
titleAndButtonsContainer, titleAndButtonsContainer
buttonsWrapper,
headerLabels: {
display: 'flex',
flexDirection: 'row',
'& div': {
display: 'flex',
alignItems: 'center'
},
'& > div:first-child': {
marginRight: 24
},
'& span': {
extend: label1,
marginLeft: 6
}
},
overflowTd: {
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis'
}
} }
export { mainStyles } export { mainStyles }