mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-02-19 15:27:16 -05:00
Prevent usernmaes ilike existing ones (case-insensitive)
This commit is contained in:
@@ -41,7 +41,7 @@ export const getUserByUsername = async (
|
||||
const res = await pg.oneOrNone(
|
||||
`select *
|
||||
from users
|
||||
where username = $1`,
|
||||
where username ilike $1`,
|
||||
username
|
||||
)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export const RequiredProfileUserForm = (props: {
|
||||
profileCreatedAlready?: boolean
|
||||
}) => {
|
||||
const {user, onSubmit, profileCreatedAlready, setProfile, profile, isSubmitting} = props
|
||||
const {updateUsername, updateDisplayName, userInfo, updateUserState} = useEditableUserInfo(user)
|
||||
const {updateDisplayName, userInfo, updateUserState, updateUsername} = useEditableUserInfo(user)
|
||||
|
||||
const [step, setStep] = useState<number>(0)
|
||||
const t = useT()
|
||||
@@ -100,7 +100,7 @@ export const RequiredProfileUserForm = (props: {
|
||||
<div className="text-ink-500 mb-6 text-lg">
|
||||
{t('profile.basics.subtitle', 'Write your own bio, your own way.')}
|
||||
</div>}
|
||||
<Col className={'gap-8 pb-[env(safe-area-inset-bottom)]'}>
|
||||
<Col className={'gap-8 pb-[env(safe-area-inset-bottom)] w-fit'}>
|
||||
{step === 0 && <Col>
|
||||
<label className={clsx(labelClassName)}>
|
||||
{t('profile.basics.display_name', 'Display name')}
|
||||
@@ -128,14 +128,13 @@ export const RequiredProfileUserForm = (props: {
|
||||
</label>
|
||||
<Row className={'items-center gap-2'}>
|
||||
<Input
|
||||
disabled={loadingUsername}
|
||||
// disabled={loadingUsername}
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChange={(e) => {
|
||||
updateUserState({username: e.target.value || ''})
|
||||
updateUserState({username: e.target.value || '', errorUsername: ''})
|
||||
}}
|
||||
onBlur={updateUsername}
|
||||
/>
|
||||
{loadingUsername && <LoadingIndicator className={'ml-2'}/>}
|
||||
</Row>
|
||||
@@ -163,13 +162,19 @@ export const RequiredProfileUserForm = (props: {
|
||||
{onSubmit && (
|
||||
<Row className={'justify-end'}>
|
||||
<Button
|
||||
disabled={!canContinue || isSubmitting}
|
||||
disabled={!canContinue || isSubmitting || loadingUsername}
|
||||
loading={isSubmitting}
|
||||
onClick={() => {
|
||||
if (step === 1) {
|
||||
onSubmit()
|
||||
} else {
|
||||
setStep(1)
|
||||
onClick={async () => {
|
||||
let success = true
|
||||
if (step === 0) {
|
||||
success = await updateUsername()
|
||||
}
|
||||
if (success) {
|
||||
if (step === 1) {
|
||||
onSubmit()
|
||||
} else {
|
||||
setStep(1)
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useState } from 'react'
|
||||
import { cleanDisplayName, cleanUsername } from 'common/util/clean-username'
|
||||
import { APIError } from 'common/api/utils'
|
||||
import { User } from 'common/user'
|
||||
import { updateUser } from 'web/lib/api'
|
||||
import {useState} from 'react'
|
||||
import {cleanDisplayName, cleanUsername} from 'common/util/clean-username'
|
||||
import {APIError} from 'common/api/utils'
|
||||
import {User} from 'common/user'
|
||||
import {updateUser} from 'web/lib/api'
|
||||
|
||||
type UserInfoState = {
|
||||
name: string
|
||||
@@ -24,19 +24,19 @@ export const useEditableUserInfo = (user: User) => {
|
||||
})
|
||||
|
||||
const updateUserState = (newState: Partial<UserInfoState>) => {
|
||||
setUserInfo((prevState) => ({ ...prevState, ...newState }))
|
||||
setUserInfo((prevState) => ({...prevState, ...newState}))
|
||||
}
|
||||
|
||||
const updateDisplayName = async () => {
|
||||
const newName = cleanDisplayName(userInfo.name)
|
||||
if (newName === user.name) return
|
||||
|
||||
updateUserState({ loadingName: true, errorName: '' })
|
||||
if (!newName) return updateUserState({ name: user.name })
|
||||
updateUserState({loadingName: true, errorName: ''})
|
||||
if (!newName) return updateUserState({name: user.name})
|
||||
|
||||
try {
|
||||
await updateUser({ name: newName })
|
||||
updateUserState({ errorName: '', name: newName })
|
||||
await updateUser({name: newName})
|
||||
updateUserState({errorName: '', name: newName})
|
||||
} catch (reason) {
|
||||
updateUserState({
|
||||
errorName: (reason as APIError).message,
|
||||
@@ -44,33 +44,34 @@ export const useEditableUserInfo = (user: User) => {
|
||||
})
|
||||
}
|
||||
|
||||
updateUserState({ loadingName: false })
|
||||
updateUserState({loadingName: false})
|
||||
}
|
||||
|
||||
const updateUsername = async () => {
|
||||
const newUsername = cleanUsername(userInfo.username)
|
||||
if (newUsername === user.username) return
|
||||
// console.log({newUsername})
|
||||
if (newUsername === user.username) return true
|
||||
|
||||
updateUserState({ loadingUsername: true, errorUsername: '' })
|
||||
updateUserState({loadingUsername: true, errorUsername: ''})
|
||||
|
||||
let success = true
|
||||
try {
|
||||
await updateUser({ username: newUsername })
|
||||
updateUserState({ errorUsername: '', username: newUsername })
|
||||
await updateUser({username: newUsername})
|
||||
updateUserState({errorUsername: ''})
|
||||
user.username = newUsername
|
||||
} catch (reason) {
|
||||
updateUserState({
|
||||
errorUsername: (reason as APIError).message,
|
||||
username: user.username,
|
||||
})
|
||||
updateUserState({errorUsername: (reason as APIError).message})
|
||||
success = false
|
||||
}
|
||||
|
||||
updateUserState({ loadingUsername: false })
|
||||
updateUserState({loadingUsername: false})
|
||||
return success
|
||||
}
|
||||
|
||||
return {
|
||||
userInfo,
|
||||
updateDisplayName,
|
||||
updateUsername,
|
||||
updateUserState,
|
||||
updateUsername,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user