[ELI5] Validate too long handles in signup (#7422)

* validate too long handles in signup

* make change handle screen generic
This commit is contained in:
Samuel Newman
2025-01-10 17:57:10 +00:00
committed by GitHub
parent d79c66af8a
commit a7da646286
3 changed files with 24 additions and 11 deletions
+10 -2
View File
@@ -19,6 +19,10 @@ export function createFullHandle(name: string, domain: string): string {
return `${name}.${domain}` return `${name}.${domain}`
} }
export function maxServiceHandleLength(domain: string): number {
return 30 - `.${(domain || '').replace(/^[.]+/, '')}`.length
}
export function isInvalidHandle(handle: string): boolean { export function isInvalidHandle(handle: string): boolean {
return handle === 'handle.invalid' return handle === 'handle.invalid'
} }
@@ -38,7 +42,11 @@ export interface IsValidHandle {
} }
// More checks from https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/handle/index.ts#L72 // More checks from https://github.com/bluesky-social/atproto/blob/main/packages/pds/src/handle/index.ts#L72
export function validateHandle(str: string, userDomain: string): IsValidHandle { export function validateHandle(
str: string,
userDomain: string,
isServiceHandle?: boolean,
): IsValidHandle {
const fullHandle = createFullHandle(str, userDomain) const fullHandle = createFullHandle(str, userDomain)
const results = { const results = {
@@ -46,7 +54,7 @@ export function validateHandle(str: string, userDomain: string): IsValidHandle {
!str || (VALIDATE_REGEX.test(fullHandle) && !str.includes('.')), !str || (VALIDATE_REGEX.test(fullHandle) && !str.includes('.')),
hyphenStartOrEnd: !str.startsWith('-') && !str.endsWith('-'), hyphenStartOrEnd: !str.startsWith('-') && !str.endsWith('-'),
frontLength: str.length >= 3, frontLength: str.length >= 3,
totalLength: fullHandle.length <= 253, totalLength: fullHandle.length <= (isServiceHandle ? 30 : 253),
} }
return { return {
@@ -172,13 +172,11 @@ function ProvidedHandlePage({
const host = serviceInfo.availableUserDomains[0] const host = serviceInfo.availableUserDomains[0]
const validation = useMemo( const validation = useMemo(
() => validateHandle(subdomain, host), () => validateHandle(subdomain, host, true),
[subdomain, host], [subdomain, host],
) )
const isTooLong = subdomain.length > 18
const isInvalid = const isInvalid =
isTooLong ||
!validation.handleChars || !validation.handleChars ||
!validation.hyphenStartOrEnd || !validation.hyphenStartOrEnd ||
!validation.totalLength !validation.totalLength
@@ -231,10 +229,10 @@ function ProvidedHandlePage({
label={_(msg`Save new handle`)} label={_(msg`Save new handle`)}
variant="solid" variant="solid"
size="large" size="large"
color={validation.overall && !isTooLong ? 'primary' : 'secondary'} color={validation.overall ? 'primary' : 'secondary'}
disabled={!validation.overall && !isTooLong} disabled={!validation.overall}
onPress={() => { onPress={() => {
if (validation.overall && !isTooLong) { if (validation.overall) {
changeHandle({handle: createFullHandle(subdomain, host)}) changeHandle({handle: createFullHandle(subdomain, host)})
} }
}}> }}>
+10 -3
View File
@@ -4,7 +4,11 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {logEvent} from '#/lib/statsig/statsig' import {logEvent} from '#/lib/statsig/statsig'
import {createFullHandle, validateHandle} from '#/lib/strings/handles' import {
createFullHandle,
maxServiceHandleLength,
validateHandle,
} from '#/lib/strings/handles'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {ScreenTransition} from '#/screens/Login/ScreenTransition' import {ScreenTransition} from '#/screens/Login/ScreenTransition'
import {useSignupContext} from '#/screens/Signup/state' import {useSignupContext} from '#/screens/Signup/state'
@@ -93,7 +97,7 @@ export function StepHandle() {
}) })
}, [dispatch, state.activeStep]) }, [dispatch, state.activeStep])
const validCheck = validateHandle(draftValue, state.userDomain) const validCheck = validateHandle(draftValue, state.userDomain, true)
return ( return (
<ScreenTransition> <ScreenTransition>
<View style={[a.gap_lg]}> <View style={[a.gap_lg]}>
@@ -166,7 +170,10 @@ export function StepHandle() {
/> />
{!validCheck.totalLength ? ( {!validCheck.totalLength ? (
<Text style={[a.text_md, a.flex_1]}> <Text style={[a.text_md, a.flex_1]}>
<Trans>No longer than 253 characters</Trans> <Trans>
No longer than {maxServiceHandleLength(state.userDomain)}{' '}
characters
</Trans>
</Text> </Text>
) : ( ) : (
<Text style={[a.text_md, a.flex_1]}> <Text style={[a.text_md, a.flex_1]}>