Enforce max question length, description length, and tag length.

This commit is contained in:
James Grugett 2022-03-09 11:08:57 -06:00
parent 4b2fd0bdc7
commit 79bd299b68
5 changed files with 31 additions and 7 deletions

View File

@ -41,3 +41,7 @@ export type Contract = {
}
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE'
export const MAX_QUESTION_LENGTH = 480
export const MAX_DESCRIPTION_LENGTH = 10000
export const MAX_TAG_LENGTH = 60

View File

@ -1,7 +1,9 @@
import { MAX_TAG_LENGTH } from '../contract'
export function parseTags(text: string) {
const regex = /(?:^|\s)(?:[#][a-z0-9_]+)/gi
const matches = (text.match(regex) || []).map((match) =>
match.trim().substring(1)
match.trim().substring(1).substring(0, MAX_TAG_LENGTH)
)
const tagSet = new Set()
const uniqueTags: string[] = []

View File

@ -1,8 +1,15 @@
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import * as _ from 'lodash'
import { chargeUser, getUser } from './utils'
import { Contract, outcomeType } from '../../common/contract'
import {
Contract,
MAX_DESCRIPTION_LENGTH,
MAX_QUESTION_LENGTH,
MAX_TAG_LENGTH,
outcomeType,
} from '../../common/contract'
import { slugify } from '../../common/util/slugify'
import { randomString } from '../../common/util/random'
import { getNewContract } from '../../common/new-contract'
@ -34,10 +41,19 @@ export const createContract = functions
const creator = await getUser(userId)
if (!creator) return { status: 'error', message: 'User not found' }
const { question, description, initialProb, ante, closeTime, tags } = data
let { question, description, initialProb, ante, closeTime, tags } = data
if (!question)
return { status: 'error', message: 'Missing question field' }
if (!question || typeof question != 'string')
return { status: 'error', message: 'Missing or invalid question field' }
question = question.slice(0, MAX_QUESTION_LENGTH)
if (typeof description !== 'string')
return { status: 'error', message: 'Invalid description field' }
description = description.slice(0, MAX_DESCRIPTION_LENGTH)
if (tags !== undefined && !_.isArray(tags))
return { status: 'error', message: 'Invalid tags field' }
tags = tags?.map((tag) => tag.toString().slice(0, MAX_TAG_LENGTH))
let outcomeType = data.outcomeType ?? 'BINARY'
if (!['BINARY', 'MULTI', 'FREE_RESPONSE'].includes(outcomeType))

View File

@ -5,7 +5,7 @@ import { Spacer } from './layout/spacer'
import { NewContract } from '../pages/create'
import { firebaseLogin, User } from '../lib/firebase/users'
import { ContractsGrid } from './contracts-list'
import { Contract } from '../../common/contract'
import { Contract, MAX_QUESTION_LENGTH } from '../../common/contract'
import { Col } from './layout/col'
import clsx from 'clsx'
import { Row } from './layout/row'
@ -121,6 +121,7 @@ export default function FeedCreate(props: {
placeholder={placeholder}
value={question}
rows={question.length > 68 ? 4 : 2}
maxLength={MAX_QUESTION_LENGTH}
onClick={(e) => e.stopPropagation()}
onChange={(e) => setQuestion(e.target.value.replace('\n', ''))}
onFocus={() => setIsExpanded(true)}

View File

@ -18,7 +18,7 @@ import { ProbabilitySelector } from '../components/probability-selector'
import { parseWordsAsTags } from '../../common/util/parse'
import { TagsList } from '../components/tags-list'
import { Row } from '../components/layout/row'
import { outcomeType } from '../../common/contract'
import { MAX_DESCRIPTION_LENGTH, outcomeType } from '../../common/contract'
export default function Create() {
const [question, setQuestion] = useState('')
@ -186,6 +186,7 @@ export function NewContract(props: { question: string; tag?: string }) {
<Textarea
className="textarea textarea-bordered w-full"
rows={3}
maxLength={MAX_DESCRIPTION_LENGTH}
placeholder={descriptionPlaceholder}
value={description}
disabled={isSubmitting}