fix: add input validation in filemanagers to prevent overwriting existing files (#1087)
This commit is contained in:
parent
e411175b7f
commit
3ec2ee2793
@ -374,12 +374,16 @@
|
||||
v-model="dialogCreateDirectory.name"
|
||||
:label="$t('Files.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keypress.enter="createDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="" text @click="dialogCreateDirectory.show = false">{{ $t('Files.Cancel') }}</v-btn>
|
||||
<v-btn color="primary" text @click="createDirectoryAction">{{ $t('Files.Create') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="createDirectoryAction">
|
||||
{{ $t('Files.Create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -399,12 +403,16 @@
|
||||
v-model="dialogRenameFile.newName"
|
||||
:label="$t('Files.Name').toString()"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="renameFileAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="" text @click="dialogRenameFile.show = false">{{ $t('Files.Cancel') }}</v-btn>
|
||||
<v-btn color="primary" text @click="renameFileAction">{{ $t('Files.Rename') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameFileAction">
|
||||
{{ $t('Files.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -424,12 +432,16 @@
|
||||
v-model="dialogRenameDirectory.newName"
|
||||
:label="$t('Files.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="renameDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="" text @click="dialogRenameDirectory.show = false">{{ $t('Files.Cancel') }}</v-btn>
|
||||
<v-btn color="primary" text @click="renameDirectoryAction">{{ $t('Files.Rename') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameDirectoryAction">
|
||||
{{ $t('Files.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -647,6 +659,16 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) {
|
||||
|
||||
private deleteSelectedDialog = false
|
||||
|
||||
private isInvalidName = true
|
||||
private nameInputRules = [
|
||||
(value: string) => !!value || this.$t('Files.InvalidNameEmpty'),
|
||||
(value: string) => !this.existsFilename(value) || this.$t('Files.InvalidNameAlreadyExists'),
|
||||
]
|
||||
|
||||
existsFilename(name: string) {
|
||||
return this.files.findIndex((file) => file.filename === name) >= 0
|
||||
}
|
||||
|
||||
get currentPath() {
|
||||
const path = this.$store.state.gui.view.gcodefiles.currentPath
|
||||
if (path === 'gcodes') return ''
|
||||
|
@ -277,6 +277,8 @@
|
||||
v-model="dialogCreateFile.name"
|
||||
:label="$t('Machine.ConfigFilesPanel.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="createFileAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -284,7 +286,7 @@
|
||||
<v-btn color="" text @click="dialogCreateFile.show = false">
|
||||
{{ $t('Machine.ConfigFilesPanel.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="createFileAction">
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="createFileAction">
|
||||
{{ $t('Machine.ConfigFilesPanel.Create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@ -306,6 +308,8 @@
|
||||
v-model="dialogRenameFile.newName"
|
||||
:label="$t('Machine.ConfigFilesPanel.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="renameFileAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -313,7 +317,7 @@
|
||||
<v-btn color="" text @click="dialogRenameFile.show = false">
|
||||
{{ $t('Machine.ConfigFilesPanel.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="renameFileAction">
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameFileAction">
|
||||
{{ $t('Machine.ConfigFilesPanel.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@ -335,6 +339,8 @@
|
||||
v-model="dialogCreateDirectory.name"
|
||||
:label="$t('Machine.ConfigFilesPanel.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="createDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -342,7 +348,7 @@
|
||||
<v-btn color="" text @click="dialogCreateDirectory.show = false">
|
||||
{{ $t('Machine.ConfigFilesPanel.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="createDirectoryAction">
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="createDirectoryAction">
|
||||
{{ $t('Machine.ConfigFilesPanel.Create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@ -364,6 +370,8 @@
|
||||
v-model="dialogRenameDirectory.newName"
|
||||
:label="$t('Machine.ConfigFilesPanel.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="renameDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -371,7 +379,7 @@
|
||||
<v-btn color="" text @click="dialogRenameDirectory.show = false">
|
||||
{{ $t('Machine.ConfigFilesPanel.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="renameDirectoryAction">
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameDirectoryAction">
|
||||
{{ $t('Machine.ConfigFilesPanel.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@ -639,6 +647,16 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin) {
|
||||
|
||||
private deleteSelectedDialog = false
|
||||
|
||||
private isInvalidName = true
|
||||
private nameInputRules = [
|
||||
(value: string) => !!value || this.$t('Files.InvalidNameEmpty'),
|
||||
(value: string) => !this.existsFilename(value) || this.$t('Files.InvalidNameAlreadyExists'),
|
||||
]
|
||||
|
||||
existsFilename(name: string) {
|
||||
return this.files.findIndex((file) => file.filename === name) >= 0
|
||||
}
|
||||
|
||||
get blockFileUpload() {
|
||||
return this.$store.state.gui.view.blockFileUpload ?? false
|
||||
}
|
||||
|
@ -237,12 +237,16 @@
|
||||
v-model="dialogRenameFile.newName"
|
||||
:label="$t('Timelapse.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keypress.enter="renameFileAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="" text @click="dialogRenameFile.show = false">{{ $t('Timelapse.Cancel') }}</v-btn>
|
||||
<v-btn color="primary" text @click="renameFileAction">{{ $t('Timelapse.Rename') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameFileAction">
|
||||
{{ $t('Timelapse.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -261,8 +265,9 @@
|
||||
ref="inputFieldCreateDirectory"
|
||||
v-model="dialogCreateDirectory.name"
|
||||
:label="$t('Timelapse.Name')"
|
||||
:rules="input_rules"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keypress.enter="createDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -270,7 +275,9 @@
|
||||
<v-btn color="" text @click="dialogCreateDirectory.show = false">
|
||||
{{ $t('Timelapse.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="createDirectoryAction">{{ $t('Timelapse.Create') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="createDirectoryAction">
|
||||
{{ $t('Timelapse.Create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -290,6 +297,8 @@
|
||||
v-model="dialogRenameDirectory.newName"
|
||||
:label="$t('Timelapse.Name')"
|
||||
required
|
||||
:rules="nameInputRules"
|
||||
@update:error="isInvalidName = !isInvalidName"
|
||||
@keyup.enter="renameDirectoryAction"></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
@ -297,7 +306,9 @@
|
||||
<v-btn color="" text @click="dialogRenameDirectory.show = false">
|
||||
{{ $t('Timelapse.Cancel') }}
|
||||
</v-btn>
|
||||
<v-btn color="primary" text @click="renameDirectoryAction">{{ $t('Timelapse.Rename') }}</v-btn>
|
||||
<v-btn :disabled="isInvalidName" color="primary" text @click="renameDirectoryAction">
|
||||
{{ $t('Timelapse.Rename') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</panel>
|
||||
</v-dialog>
|
||||
@ -496,7 +507,15 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
|
||||
|
||||
private deleteSelectedDialog = false
|
||||
|
||||
private input_rules = [(value: string) => value.indexOf(' ') === -1 || 'Name contains spaces!']
|
||||
private isInvalidName = true
|
||||
private nameInputRules = [
|
||||
(value: string) => !!value || this.$t('Files.InvalidNameEmpty'),
|
||||
(value: string) => !this.existsFilename(value) || this.$t('Files.InvalidNameAlreadyExists'),
|
||||
]
|
||||
|
||||
existsFilename(name: string) {
|
||||
return this.files.findIndex((file) => file.filename === name) >= 0
|
||||
}
|
||||
|
||||
get headers() {
|
||||
return [
|
||||
@ -593,14 +612,15 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) {
|
||||
}
|
||||
|
||||
createDirectoryAction() {
|
||||
if (this.dialogCreateDirectory.name.length && this.dialogCreateDirectory.name.indexOf(' ') === -1) {
|
||||
this.dialogCreateDirectory.show = false
|
||||
this.$socket.emit(
|
||||
'server.files.post_directory',
|
||||
{ path: this.currentPath + '/' + this.dialogCreateDirectory.name },
|
||||
{ action: 'files/getCreateDir' }
|
||||
)
|
||||
}
|
||||
this.dialogCreateDirectory.show = false
|
||||
|
||||
this.$socket.emit(
|
||||
'server.files.post_directory',
|
||||
{
|
||||
path: this.currentPath + '/' + this.dialogCreateDirectory.name,
|
||||
},
|
||||
{ action: 'files/getCreateDir' }
|
||||
)
|
||||
}
|
||||
|
||||
refreshFileList() {
|
||||
|
@ -181,6 +181,8 @@
|
||||
"GCodeFiles": "G-Code Dateien",
|
||||
"GcodesRootDirectoryDoesntExists": "Keinen G-Code Ordner gefunden. Bitte überprüfe die Option \"path\" im Abschnitt [virtual_sdcard] in der Klipper Konfiguration.",
|
||||
"HiddenFiles": "Versteckte Dateien",
|
||||
"InvalidNameEmpty": "Feld darf nicht leer sein!",
|
||||
"InvalidNameAlreadyExists": "Name existiert bereits, bitte wähle einen anderen Namen.",
|
||||
"LastEndTime": "Letzte Endzeit",
|
||||
"LastFilamentUsed": "Letzter Filamentverbrauch",
|
||||
"LastModified": "Zuletzt geändert",
|
||||
|
@ -181,6 +181,8 @@
|
||||
"GCodeFiles": "G-Code Files",
|
||||
"GcodesRootDirectoryDoesntExists": "No G-Code directory found. Please check option \"path\" in the [virtual_sdcard] section of the Klipper configuration.",
|
||||
"HiddenFiles": "Hidden files",
|
||||
"InvalidNameEmpty": "Input must not be empty!",
|
||||
"InvalidNameAlreadyExists": "Name already exists, please choose another name.",
|
||||
"LastEndTime": "Last End Time",
|
||||
"LastFilamentUsed": "Last Filament Used",
|
||||
"LastModified": "Last modified",
|
||||
|
Loading…
x
Reference in New Issue
Block a user