Enforce max question length, description length, and tag length.
This commit is contained in:
parent
4b2fd0bdc7
commit
79bd299b68
|
@ -41,3 +41,7 @@ export type Contract = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE'
|
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
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
import { MAX_TAG_LENGTH } from '../contract'
|
||||||
|
|
||||||
export function parseTags(text: string) {
|
export function parseTags(text: string) {
|
||||||
const regex = /(?:^|\s)(?:[#][a-z0-9_]+)/gi
|
const regex = /(?:^|\s)(?:[#][a-z0-9_]+)/gi
|
||||||
const matches = (text.match(regex) || []).map((match) =>
|
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 tagSet = new Set()
|
||||||
const uniqueTags: string[] = []
|
const uniqueTags: string[] = []
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
import * as functions from 'firebase-functions'
|
import * as functions from 'firebase-functions'
|
||||||
import * as admin from 'firebase-admin'
|
import * as admin from 'firebase-admin'
|
||||||
|
import * as _ from 'lodash'
|
||||||
|
|
||||||
import { chargeUser, getUser } from './utils'
|
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 { slugify } from '../../common/util/slugify'
|
||||||
import { randomString } from '../../common/util/random'
|
import { randomString } from '../../common/util/random'
|
||||||
import { getNewContract } from '../../common/new-contract'
|
import { getNewContract } from '../../common/new-contract'
|
||||||
|
@ -34,10 +41,19 @@ export const createContract = functions
|
||||||
const creator = await getUser(userId)
|
const creator = await getUser(userId)
|
||||||
if (!creator) return { status: 'error', message: 'User not found' }
|
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)
|
if (!question || typeof question != 'string')
|
||||||
return { status: 'error', message: 'Missing question field' }
|
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'
|
let outcomeType = data.outcomeType ?? 'BINARY'
|
||||||
if (!['BINARY', 'MULTI', 'FREE_RESPONSE'].includes(outcomeType))
|
if (!['BINARY', 'MULTI', 'FREE_RESPONSE'].includes(outcomeType))
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { Spacer } from './layout/spacer'
|
||||||
import { NewContract } from '../pages/create'
|
import { NewContract } from '../pages/create'
|
||||||
import { firebaseLogin, User } from '../lib/firebase/users'
|
import { firebaseLogin, User } from '../lib/firebase/users'
|
||||||
import { ContractsGrid } from './contracts-list'
|
import { ContractsGrid } from './contracts-list'
|
||||||
import { Contract } from '../../common/contract'
|
import { Contract, MAX_QUESTION_LENGTH } from '../../common/contract'
|
||||||
import { Col } from './layout/col'
|
import { Col } from './layout/col'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { Row } from './layout/row'
|
import { Row } from './layout/row'
|
||||||
|
@ -121,6 +121,7 @@ export default function FeedCreate(props: {
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={question}
|
value={question}
|
||||||
rows={question.length > 68 ? 4 : 2}
|
rows={question.length > 68 ? 4 : 2}
|
||||||
|
maxLength={MAX_QUESTION_LENGTH}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
onChange={(e) => setQuestion(e.target.value.replace('\n', ''))}
|
onChange={(e) => setQuestion(e.target.value.replace('\n', ''))}
|
||||||
onFocus={() => setIsExpanded(true)}
|
onFocus={() => setIsExpanded(true)}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { ProbabilitySelector } from '../components/probability-selector'
|
||||||
import { parseWordsAsTags } from '../../common/util/parse'
|
import { parseWordsAsTags } from '../../common/util/parse'
|
||||||
import { TagsList } from '../components/tags-list'
|
import { TagsList } from '../components/tags-list'
|
||||||
import { Row } from '../components/layout/row'
|
import { Row } from '../components/layout/row'
|
||||||
import { outcomeType } from '../../common/contract'
|
import { MAX_DESCRIPTION_LENGTH, outcomeType } from '../../common/contract'
|
||||||
|
|
||||||
export default function Create() {
|
export default function Create() {
|
||||||
const [question, setQuestion] = useState('')
|
const [question, setQuestion] = useState('')
|
||||||
|
@ -186,6 +186,7 @@ export function NewContract(props: { question: string; tag?: string }) {
|
||||||
<Textarea
|
<Textarea
|
||||||
className="textarea textarea-bordered w-full"
|
className="textarea textarea-bordered w-full"
|
||||||
rows={3}
|
rows={3}
|
||||||
|
maxLength={MAX_DESCRIPTION_LENGTH}
|
||||||
placeholder={descriptionPlaceholder}
|
placeholder={descriptionPlaceholder}
|
||||||
value={description}
|
value={description}
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user