import { useQuery, useMutation, useLazyQuery, gql } from '@apollo/client' import Chip from '@mui/material/Chip' import Switch from '@mui/material/Switch' import { startAttestation } from '@simplewebauthn/browser' import * as R from 'ramda' import React, { useReducer, useState, useContext } from 'react' import TitleSection from 'src/components/layout/TitleSection' import DataTable from 'src/components/tables/DataTable' import WhiteKeyIcon from 'src/styling/icons/button/key/white.svg?react' import KeyIcon from 'src/styling/icons/button/key/zodiac.svg?react' import WhiteLockIcon from 'src/styling/icons/button/lock/white.svg?react' import LockIcon from 'src/styling/icons/button/lock/zodiac.svg?react' import WhiteUserRoleIcon from 'src/styling/icons/button/user-role/white.svg?react' import UserRoleIcon from 'src/styling/icons/button/user-role/zodiac.svg?react' import AppContext from 'src/AppContext' import { ActionButton, Link } from 'src/components/buttons' import { IP_CHECK_REGEX } from 'src/utils/constants' import ChangeRoleModal from './modals/ChangeRoleModal' import CreateUserModal from './modals/CreateUserModal' import EnableUserModal from './modals/EnableUserModal' import FIDOModal from './modals/FIDOModal' import Reset2FAModal from './modals/Reset2FAModal' import ResetPasswordModal from './modals/ResetPasswordModal' import classes from './UserManagement.module.css' const GET_USERS = gql` query users { users { id username role enabled last_accessed last_accessed_from last_accessed_address } } ` const GENERATE_ATTESTATION = gql` query generateAttestationOptions($userID: ID!, $domain: String!) { generateAttestationOptions(userID: $userID, domain: $domain) } ` const VALIDATE_ATTESTATION = gql` mutation validateAttestation( $userID: ID! $attestationResponse: JSONObject! $domain: String! ) { validateAttestation( userID: $userID attestationResponse: $attestationResponse domain: $domain ) } ` const initialState = { showCreateUserModal: false, showResetPasswordModal: false, showReset2FAModal: false, showRoleModal: false, showEnableUserModal: false, } const reducer = (_, action) => { const { type, payload } = action switch (type) { case 'close': return initialState case 'open': return { ...initialState, [payload]: true } default: return initialState } } const roleMapper = { user: 'Regular', superuser: 'Superuser', } const Users = () => { const { userData } = useContext(AppContext) const { data: userResponse } = useQuery(GET_USERS) const [state, dispatch] = useReducer(reducer, initialState) const [userInfo, setUserInfo] = useState(null) const [validateAttestation] = useMutation(VALIDATE_ATTESTATION, { onCompleted: () => { // TODO: show a brief popup to have UX feedback? }, }) const [generateAttestationOptions] = useLazyQuery(GENERATE_ATTESTATION, { onCompleted: ({ generateAttestationOptions: options }) => { return startAttestation(options).then(res => { validateAttestation({ variables: { userID: userInfo.id, attestationResponse: res, domain: window.location.hostname, }, }) }) }, }) const elements = [ { header: 'Login', width: 307, textAlign: 'left', size: 'sm', view: u => { if (userData.id === u.id) return (