fix: component behavior for obfuscated fields
This commit is contained in:
parent
fcfe16d5eb
commit
54a19b25c1
13 changed files with 233 additions and 42 deletions
|
|
@ -4,11 +4,8 @@ import { TextInput } from '../base'
|
|||
|
||||
const SecretInput = memo(({ value, onFocus, onBlur, ...props }) => {
|
||||
const [focused, setFocused] = useState(false)
|
||||
|
||||
const isPasswordFilled = props.isPasswordFilled
|
||||
const placeholder = '⚬ ⚬ ⚬ This field is set ⚬ ⚬ ⚬'
|
||||
const previouslyFilled = !!value
|
||||
const tempValue = previouslyFilled ? '' : value
|
||||
|
||||
const innerOnFocus = event => {
|
||||
setFocused(true)
|
||||
onFocus && onFocus(event)
|
||||
|
|
@ -26,9 +23,9 @@ const SecretInput = memo(({ value, onFocus, onBlur, ...props }) => {
|
|||
onFocus={innerOnFocus}
|
||||
onBlur={innerOnBlur}
|
||||
value={value}
|
||||
InputProps={{ value: !focused ? tempValue : value }}
|
||||
InputLabelProps={{ shrink: previouslyFilled || focused }}
|
||||
placeholder={previouslyFilled ? placeholder : ''}
|
||||
InputProps={{ value: value }}
|
||||
InputLabelProps={{ shrink: isPasswordFilled || value || focused }}
|
||||
placeholder={isPasswordFilled ? placeholder : ''}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -26,8 +26,9 @@ const TextInput = memo(
|
|||
...props
|
||||
}) => {
|
||||
const classes = useStyles({ textAlign, width, size })
|
||||
const filled = !error && !R.isNil(value) && !R.isEmpty(value)
|
||||
|
||||
const isPasswordFilled = props.isPasswordFilled
|
||||
const isTextFilled = !error && !R.isNil(value) && !R.isEmpty(value)
|
||||
const filled = isPasswordFilled || isTextFilled
|
||||
const inputClasses = {
|
||||
[classes.bold]: bold
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ import { SecretInput } from '../base'
|
|||
const SecretInputFormik = memo(({ ...props }) => {
|
||||
const { name, onChange, onBlur, value } = props.field
|
||||
const { touched, errors } = props.form
|
||||
const isPasswordFilled = props.isPasswordFilled
|
||||
|
||||
const error = !!(touched[name] && errors[name])
|
||||
const error = !isPasswordFilled && !!(touched[name] && errors[name])
|
||||
|
||||
return (
|
||||
<SecretInput
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import * as R from 'ramda'
|
|||
import React, { useState } from 'react'
|
||||
|
||||
import Modal from 'src/components/Modal'
|
||||
import { SecretInput } from 'src/components/inputs/formik'
|
||||
import TitleSection from 'src/components/layout/TitleSection'
|
||||
import SingleRowTable from 'src/components/single-row-table/SingleRowTable'
|
||||
import { formatLong } from 'src/utils/string'
|
||||
|
|
@ -56,6 +57,47 @@ const Services = () => {
|
|||
}))(faceElements)
|
||||
}
|
||||
|
||||
const getElements = ({ code, elements }) => {
|
||||
return R.compose(
|
||||
R.map(elem => {
|
||||
return elem.component === SecretInput
|
||||
? R.assoc(
|
||||
'inputProps',
|
||||
{
|
||||
isPasswordFilled:
|
||||
!R.isNil(accounts[code]) &&
|
||||
!R.isNil(R.path([elem.code], accounts[code]))
|
||||
},
|
||||
elem
|
||||
)
|
||||
: R.identity(elem)
|
||||
})
|
||||
)(elements)
|
||||
}
|
||||
|
||||
const getAccounts = ({ elements, code }) => {
|
||||
const account = accounts[code]
|
||||
const passwordFields = R.compose(
|
||||
R.reject(R.isNil),
|
||||
R.map(({ component, code }) => (component === SecretInput ? code : null))
|
||||
)(elements)
|
||||
return R.compose(
|
||||
R.mapObjIndexed((value, key, obj) =>
|
||||
R.includes(key, passwordFields) ? '' : value
|
||||
)
|
||||
)(account)
|
||||
}
|
||||
|
||||
const getValidationSchema = ({
|
||||
validationSchema,
|
||||
code,
|
||||
hasSecret,
|
||||
getValidationSchema
|
||||
}) => {
|
||||
if (!hasSecret) return validationSchema
|
||||
return getValidationSchema(accounts[code])
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<TitleSection title="3rd Party Services" />
|
||||
|
|
@ -83,9 +125,9 @@ const Services = () => {
|
|||
variables: { accounts: { [editingSchema.code]: it } }
|
||||
})
|
||||
}
|
||||
elements={editingSchema.elements}
|
||||
validationSchema={editingSchema.validationSchema}
|
||||
value={accounts[editingSchema.code]}
|
||||
elements={getElements(editingSchema)}
|
||||
validationSchema={getValidationSchema(editingSchema)}
|
||||
value={getAccounts(editingSchema)}
|
||||
/>
|
||||
</Modal>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ import {
|
|||
Autocomplete
|
||||
} from 'src/components/inputs/formik'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
const isDefined = it => it && it.length
|
||||
|
||||
export default {
|
||||
code: 'bitgo',
|
||||
name: 'BitGo',
|
||||
hasSecret: true,
|
||||
title: 'BitGo (Wallet)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -127,5 +130,51 @@ export default {
|
|||
environment: Yup.string()
|
||||
.matches(/(prod|test)/)
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
token: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
BTCWalletId: Yup.string().max(100, 'Too long'),
|
||||
BTCWalletPassphrase: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.when('BTCWalletId', {
|
||||
is: isDefined,
|
||||
then: Yup.string().test(secretTest(account?.BTCWalletPassphrase))
|
||||
}),
|
||||
LTCWalletId: Yup.string().max(100, 'Too long'),
|
||||
LTCWalletPassphrase: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.when('LTCWalletId', {
|
||||
is: isDefined,
|
||||
then: Yup.string().test(secretTest(account?.LTCWalletPassphrase))
|
||||
}),
|
||||
ZECWalletId: Yup.string().max(100, 'Too long'),
|
||||
ZECWalletPassphrase: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.when('ZECWalletId', {
|
||||
is: isDefined,
|
||||
then: Yup.string().test(secretTest(account?.ZECWalletPassphrase))
|
||||
}),
|
||||
BCHWalletId: Yup.string().max(100, 'Too long'),
|
||||
BCHWalletPassphrase: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.when('BCHWalletId', {
|
||||
is: isDefined,
|
||||
then: Yup.string().test(secretTest(account?.BCHWalletPassphrase))
|
||||
}),
|
||||
DASHWalletId: Yup.string().max(100, 'Too long'),
|
||||
DASHWalletPassphrase: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.when('DASHWalletId', {
|
||||
is: isDefined,
|
||||
then: Yup.string().test(secretTest(account?.DASHWalletPassphrase))
|
||||
}),
|
||||
environment: Yup.string()
|
||||
.matches(/(prod|test)/)
|
||||
.required()
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ import * as Yup from 'yup'
|
|||
import SecretInputFormik from 'src/components/inputs/formik/SecretInput'
|
||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
export default {
|
||||
code: 'bitstamp',
|
||||
name: 'Bitstamp',
|
||||
hasSecret: true,
|
||||
title: 'Bitstamp (Exchange)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -28,7 +31,6 @@ export default {
|
|||
component: SecretInputFormik
|
||||
}
|
||||
],
|
||||
|
||||
validationSchema: Yup.object().shape({
|
||||
clientId: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
|
|
@ -39,5 +41,19 @@ export default {
|
|||
secret: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
clientId: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
key: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
secret: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.test(secretTest(account?.secret))
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
|||
export default {
|
||||
code: 'blockcypher',
|
||||
name: 'Blockcypher',
|
||||
hasSecret: false,
|
||||
title: 'Blockcypher (Payments)',
|
||||
elements: [
|
||||
{
|
||||
|
|
|
|||
12
new-lamassu-admin/src/pages/Services/schemas/helper.js
Normal file
12
new-lamassu-admin/src/pages/Services/schemas/helper.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import * as R from 'ramda'
|
||||
|
||||
const secretTest = secret => ({
|
||||
test(val) {
|
||||
if (R.isNil(secret) && R.isNil(val)) {
|
||||
return this.createError()
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
export default secretTest
|
||||
|
|
@ -3,9 +3,12 @@ import * as Yup from 'yup'
|
|||
import SecretInputFormik from 'src/components/inputs/formik/SecretInput'
|
||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
export default {
|
||||
code: 'infura',
|
||||
name: 'Infura',
|
||||
hasSecret: true,
|
||||
title: 'Infura (Wallet)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -37,5 +40,19 @@ export default {
|
|||
endpoint: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
apiKey: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
apiSecret: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.test(secretTest(account?.apiSecret)),
|
||||
endpoint: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ import * as Yup from 'yup'
|
|||
import SecretInputFormik from 'src/components/inputs/formik/SecretInput'
|
||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
export default {
|
||||
code: 'itbit',
|
||||
name: 'itBit',
|
||||
hasSecret: true,
|
||||
title: 'itBit (Exchange)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -46,5 +49,22 @@ export default {
|
|||
clientSecret: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
userId: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
walletId: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
clientKey: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
clientSecret: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.test(secretTest(account?.clientSecret))
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ import * as Yup from 'yup'
|
|||
import SecretInputFormik from 'src/components/inputs/formik/SecretInput'
|
||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
export default {
|
||||
code: 'kraken',
|
||||
name: 'Kraken',
|
||||
hasSecret: true,
|
||||
title: 'Kraken (Exchange)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -28,5 +31,16 @@ export default {
|
|||
privateKey: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
apiKey: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
privateKey: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.test(secretTest(account?.privateKey))
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
|||
export default {
|
||||
code: 'mailgun',
|
||||
name: 'Mailgun',
|
||||
hasSecret: false,
|
||||
title: 'Mailgun (Email)',
|
||||
elements: [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ import * as Yup from 'yup'
|
|||
import SecretInputFormik from 'src/components/inputs/formik/SecretInput'
|
||||
import TextInputFormik from 'src/components/inputs/formik/TextInput'
|
||||
|
||||
import secretTest from './helper'
|
||||
|
||||
export default {
|
||||
code: 'twilio',
|
||||
name: 'Twilio',
|
||||
hasSecret: true,
|
||||
title: 'Twilio (SMS)',
|
||||
elements: [
|
||||
{
|
||||
|
|
@ -44,5 +47,22 @@ export default {
|
|||
toNumber: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
})
|
||||
}),
|
||||
getValidationSchema: account => {
|
||||
const schema = {
|
||||
accountSid: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
authToken: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.test(secretTest(account?.authToken)),
|
||||
fromNumber: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required(),
|
||||
toNumber: Yup.string()
|
||||
.max(100, 'Too long')
|
||||
.required()
|
||||
}
|
||||
return Yup.object().shape(schema)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue