Skip to content

Commit

Permalink
validate account value
Browse files Browse the repository at this point in the history
  • Loading branch information
TateB committed Jan 23, 2024
1 parent d4a8abf commit 628db9a
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
3 changes: 2 additions & 1 deletion public/locales/en/register.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@
"errors": {
"labelRequired": "A record key is required",
"duplicateRecord": "Duplicate record key",
"avatarReserved": "Key is being used by avatar manager"
"avatarReserved": "Key is being used by avatar manager",
"invalidValue": "Invalid value"
},
"confirmations": {
"publicNotice": {
Expand Down
27 changes: 0 additions & 27 deletions src/hooks/useProfileEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ import {
formSafeKey,
getDirtyFields,
} from '@app/utils/editor'
import { validateCryptoAddress } from '@app/validators/validateAddress'

import { ContentHashProvider } from '../utils/contenthash'
import { validateContentHash } from '../validators/validateContentHash'

const getFieldsByType = (type: 'text' | 'addr' | 'contentHash', data: ProfileEditorType) => {
const entries = []
Expand Down Expand Up @@ -335,28 +331,6 @@ const useProfileEditor = ({ callback, profile, overwrites, returnAllFields }: Pr

const hasChanges = Object.keys(formState.dirtyFields || {}).length > 0

const validateCustomInputKey = (key?: string) => () => {
if (!key) return true
const editor = getValues()
const allTextKeys = [
...(editor.avatar ? ['avatar'] : []),
...Object.keys(editor.general || {}),
...Object.keys(editor.accounts || {}),
...Object.keys(editor.other || {}),
]
return allTextKeys.filter((existingKey) => existingKey === key.trim()).length > 1
? t('errors.duplicateKey', { value: key })
: true
}

const validateForGroupAndKey = (group: string, key: string) => {
if (group === 'address')
return (value: string | undefined) => validateCryptoAddress({ coin: key, address: value })
if (group === 'website') return validateContentHash(key as ContentHashProvider)
if (group === 'other') return validateCustomInputKey(key)
return () => true
}

return {
register,
unregister,
Expand Down Expand Up @@ -402,7 +376,6 @@ const useProfileEditor = ({ callback, profile, overwrites, returnAllFields }: Pr
AddButtonProps,
setAvatar,
hasChanges,
validateForGroupAndKey,
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/hooks/useProfileEditorForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { ProfileRecord, ProfileRecordGroup } from '@app/constants/profileRecordOptions'
import { supportedAddresses } from '@app/constants/supportedAddresses'
import { AvatarEditorType } from '@app/types'
import { validateAccount } from '@app/validators/validateAccount'
import { validateCryptoAddress } from '@app/validators/validateAddress'
import { validateContentHash } from '@app/validators/validateContentHash'
import { validateUrl } from '@app/validators/validateUrl'
Expand Down Expand Up @@ -110,6 +111,13 @@ export const useProfileEditorForm = (existingRecords: ProfileRecord[]) => {
return t('steps.profile.errors.duplicateRecord') as string
return true
}
if (record.group === 'social')
return (value?: string) => {
if (!value) return true
const isValid = validateAccount({ key: record.key, value })
if (!isValid) return t('steps.profile.errors.invalidValue') as string
return true
}
return () => true
}

Expand Down
50 changes: 50 additions & 0 deletions src/validators/validateAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* twitter:
* - 1-15 chars
* - technically 4-15 for new users but existing usernames can be shorter
* - case sensitive alphanumeric + underscore
*/
const twitterRegex = /^[A-Za-z0-9_]{1,15}$/

/* github:
* - 1-39 chars
* - case insensitive alphanumeric + hyphen
* - cannot start with hyphen
* - cannot have consecutive hyphens
* - cannot end with hyphen for new users, but existing usernames can
*/
const githubRegex = /^[a-z\\d](?:[a-z\\d]-?){0,38}$/i

/* discord:
* - 2-32 chars
* - case insensitive alphanumeric + underscore + dash
* - cannot use consecutive periods
*/
const discordRegex = /^(?!.*\.\.)[a-z0-9_.]{2,32}$/

/* telegram:
* - 5-32 chars
* - case sensitive alphanumeric + underscore
*/
const telegramRegex = /^[A-Za-z0-9_]{5,32}$/

/* email:
* - basic non-greedy regex
*/
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

export const validateAccount = ({ key, value }: { key: string; value: string }): boolean => {
switch (key) {
case 'com.twitter':
return twitterRegex.test(value)
case 'com.github':
return githubRegex.test(value)
case 'com.discord':
return discordRegex.test(value)
case 'org.telegram':
return telegramRegex.test(value)
case 'email':
return emailRegex.test(value)
default:
return true
}
}

0 comments on commit 628db9a

Please sign in to comment.