Enforce userName and title can only containing aphlanumeric and dashes

Enforce data integrity basically, important since they're used for urls
I could do url encoding, but the idea is the the url looks good so
its helping keep the feel of the website
This commit is contained in:
Kurt Hutten
2020-11-08 17:56:08 +11:00
parent 5034cf98c3
commit 8107c7dcea
6 changed files with 16 additions and 9 deletions

View File

@@ -39,6 +39,9 @@ export const createPart = async ({ input }) => {
export const updatePart = async ({ id, input }) => { export const updatePart = async ({ id, input }) => {
requireAuth() requireAuth()
await requireOwnership({partId: id}) await requireOwnership({partId: id})
if(input.title) {
input.title = input.title.replace(/([^a-zA-Z\d_:])/g, '-')
}
return db.part.update({ return db.part.update({
data: foreignKeyReplacement(input), data: foreignKeyReplacement(input),
where: { id }, where: { id },

View File

@@ -40,6 +40,9 @@ export const updateUser = ({ id, input }) => {
export const updateUserByUserName = async ({ userName, input }) => { export const updateUserByUserName = async ({ userName, input }) => {
requireAuth() requireAuth()
await requireOwnership({userName}) await requireOwnership({userName})
if(input.userName) {
input.userName = input.userName.replace(/([^a-zA-Z\d_:])/g, '-')
}
return db.user.update({ return db.user.update({
data: input, data: input,
where: { userName }, where: { userName },

View File

@@ -64,7 +64,7 @@ const EmojiReaction = ({ emotes, userEmotes, onEmote = () => {}, className }) =>
<span <span
className={getActiveClasses( className={getActiveClasses(
"rounded-full tracking-wide hover:bg-indigo-100 p-1 mx-px transform hover:-translate-y-px transition-all duration-150 border-indigo-400", "rounded-full tracking-wide hover:bg-indigo-100 p-1 mx-px transform hover:-translate-y-px transition-all duration-150 border-indigo-400",
{'border': currentUser && userEmotes.includes(emote.emoji)} {'border': currentUser && userEmotes?.includes(emote.emoji)}
)} )}
style={textShadow} style={textShadow}
key={`${emote.emoji}--${i}`} key={`${emote.emoji}--${i}`}

View File

@@ -30,15 +30,15 @@ const PartProfile = ({
navigate(routes.part2({userName: userPart.userName, partTitle: part.title}))}, navigate(routes.part2({userName: userPart.userName, partTitle: part.title}))},
[currentUser]) [currentUser])
const [input, setInput] = useState({ const [input, setInput] = useState({
title: part.title, title: part?.title,
mainImage: part.mainImage, mainImage: part?.mainImage,
description: part.description, description: part?.description,
}) })
const setProperty = (property, value) => setInput({ const setProperty = (property, value) => setInput({
...input, ...input,
[property]: value, [property]: value,
}) })
const onTitleChange = ({target}) => setProperty('title', target.value) const onTitleChange = ({target}) => setProperty('title', target.value.replace(/([^a-zA-Z\d_:])/g, '-'))
const onDescriptionChange = (description) => setProperty('description', description()) const onDescriptionChange = (description) => setProperty('description', description())
const onImageUpload = ({cloudinaryPublicId}) => setProperty('mainImage', cloudinaryPublicId) const onImageUpload = ({cloudinaryPublicId}) => setProperty('mainImage', cloudinaryPublicId)
const onEditSaveClick = () => { const onEditSaveClick = () => {
@@ -122,7 +122,7 @@ const PartProfile = ({
<h3 className="text-indigo-800 text-lg font-roboto tracking-wider mb-4" >Comments</h3> <h3 className="text-indigo-800 text-lg font-roboto tracking-wider mb-4" >Comments</h3>
<ul> <ul>
{part.Comment.map(({text, user, id}) => ( {part?.Comment.map(({text, user, id}) => (
<li key={id} className="flex mb-6"> <li key={id} className="flex mb-6">
<div className="w-8 h-8 overflow-hidden rounded-full border border-indigo-300 shadow flex-shrink-0"> <div className="w-8 h-8 overflow-hidden rounded-full border border-indigo-300 shadow flex-shrink-0">
<ImageUploader <ImageUploader

View File

@@ -41,9 +41,10 @@ const UserProfile = ({user, isEditable, loading, onSave, error}) => {
/> />
</div> </div>
<div className="ml-6 flex flex-col justify-between"> <div className="ml-6 flex flex-col justify-between">
<ProfileTextInput fields={editableTextFields} onChange={(textFields) => setInput({ <ProfileTextInput fields={editableTextFields} onChange={({userName, name}) => setInput({
...input, ...input,
...textFields, name,
userName: userName.replace(/([^a-zA-Z\d_:])/g, '-'),
})} isEditable={isEditable}/> })} isEditable={isEditable}/>
{isEditable ? {isEditable ?
<Button className="bg-indigo-200" iconName="plus" onClick={() => onSave(user.userName, input)}>Save Profile</Button> : // TODO replace pencil with a save icon <Button className="bg-indigo-200" iconName="plus" onClick={() => onSave(user.userName, input)}>Save Profile</Button> : // TODO replace pencil with a save icon

View File

@@ -1,4 +1,4 @@
export const countEmotes = (reactions) => { export const countEmotes = (reactions = []) => {
// would be good to do this sever side // would be good to do this sever side
// counting unique emojis, and limiting to the 5 largest // counting unique emojis, and limiting to the 5 largest
const emoteCounts = {} const emoteCounts = {}