Add server-side validation for snippet names
This commit is contained in:
parent
74a2b54880
commit
2d12a1a8fa
|
@ -13,13 +13,13 @@
|
|||
import { snippets } from "stores/builder"
|
||||
import { getSequentialName } from "helpers/duplicate"
|
||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||
import { ValidSnippetNameRegex } from "@budibase/shared-core"
|
||||
|
||||
export let snippet
|
||||
|
||||
export const show = () => drawer.show()
|
||||
export const hide = () => drawer.hide()
|
||||
|
||||
const roughValidNameRegex = /^[_$A-Z\xA0-\uFFFF][_$A-Z0-9\xA0-\uFFFF]*$/i
|
||||
const firstCharNumberRegex = /^[0-9].*$/
|
||||
|
||||
let drawer
|
||||
|
@ -43,7 +43,7 @@
|
|||
drawer.hide()
|
||||
notifications.success(`Snippet ${newSnippet.name} saved`)
|
||||
} catch (error) {
|
||||
notifications.error("Error saving snippet")
|
||||
notifications.error(error.message || "Error saving snippet")
|
||||
}
|
||||
loading = false
|
||||
}
|
||||
|
@ -69,21 +69,16 @@
|
|||
if (!name?.length) {
|
||||
return "Name is required"
|
||||
}
|
||||
if (firstCharNumberRegex.test(name)) {
|
||||
return "Can't start with a number"
|
||||
}
|
||||
if (!roughValidNameRegex.test(name)) {
|
||||
return "No special characters or spaces"
|
||||
}
|
||||
if (snippets.some(snippet => snippet.name === name)) {
|
||||
return "That name is already in use"
|
||||
}
|
||||
const js = `(function ${name}(){return true})()`
|
||||
try {
|
||||
return eval(js) === true ? null : "Invalid name"
|
||||
} catch (error) {
|
||||
return "Invalid name"
|
||||
if (firstCharNumberRegex.test(name)) {
|
||||
return "Can't start with a number"
|
||||
}
|
||||
if (!ValidSnippetNameRegex.test(name)) {
|
||||
return "No special characters or spaces"
|
||||
}
|
||||
return null
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { auth, permissions } from "@budibase/backend-core"
|
|||
import { DataSourceOperation } from "../../../constants"
|
||||
import { WebhookActionType } from "@budibase/types"
|
||||
import Joi from "joi"
|
||||
import { ValidSnippetNameRegex } from "@budibase/shared-core"
|
||||
|
||||
const OPTIONAL_STRING = Joi.string().optional().allow(null).allow("")
|
||||
const OPTIONAL_NUMBER = Joi.number().optional().allow(null)
|
||||
|
@ -226,6 +227,21 @@ export function applicationValidator(opts = { isCreate: true }) {
|
|||
base.name = appNameValidator.optional()
|
||||
}
|
||||
|
||||
const snippetValidator = Joi.array()
|
||||
.optional()
|
||||
.items(
|
||||
Joi.object({
|
||||
name: Joi.string()
|
||||
.pattern(new RegExp(ValidSnippetNameRegex))
|
||||
.error(
|
||||
new Error(
|
||||
"Snippet name cannot include spaces or special characters, and cannot start with a number"
|
||||
)
|
||||
),
|
||||
code: OPTIONAL_STRING,
|
||||
})
|
||||
)
|
||||
|
||||
return auth.joiValidator.body(
|
||||
Joi.object({
|
||||
_id: OPTIONAL_STRING,
|
||||
|
@ -235,6 +251,7 @@ export function applicationValidator(opts = { isCreate: true }) {
|
|||
template: Joi.object({
|
||||
templateString: OPTIONAL_STRING,
|
||||
}).unknown(true),
|
||||
snippets: snippetValidator,
|
||||
}).unknown(true)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ export enum BuilderSocketEvent {
|
|||
export const SocketSessionTTL = 60
|
||||
export const ValidQueryNameRegex = /^[^()]*$/
|
||||
export const ValidColumnNameRegex = /^[_a-zA-Z0-9\s]*$/g
|
||||
export const ValidSnippetNameRegex = /^[a-z-_][a-z0-9-_]*$/i
|
||||
|
||||
export const REBOOT_CRON = "@reboot"
|
||||
|
||||
|
|
Loading…
Reference in New Issue