fixed recorders (validate migration)

This commit is contained in:
2020-07-31 14:40:13 +02:00
parent f07716b946
commit c0d6da48c9
6 changed files with 130 additions and 64 deletions

15
package-lock.json generated
View File

@@ -10745,6 +10745,21 @@
"is-path-inside": "^1.0.0"
}
},
"is-ip": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz",
"integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==",
"requires": {
"ip-regex": "^4.0.0"
},
"dependencies": {
"ip-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz",
"integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA=="
}
}
},
"is-natural-number": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",

View File

@@ -20,6 +20,7 @@
"bootstrap-vue": "^2.16.0",
"core-js": "^3.6.5",
"i": "^0.3.6",
"is-ip": "^3.1.0",
"jquery": "^3.5.1",
"js-cookie": "^2.2.1",
"node-sass": "^4.14.1",

View File

@@ -54,7 +54,7 @@
<b-nav-item-dropdown text="Lang" right>
<b-dropdown-item v-for="(lang, i) in langs"
v-bind:key="lang"
@click="$i18n.locale=lang">{{ lang }}
@click="setLang(lang)">{{ lang }}
</b-dropdown-item>
</b-nav-item-dropdown>
@@ -87,6 +87,7 @@
<script>
import {EventBus, getRemainingJwtValiditySeconds} from '@/utils';
import { localize } from 'vee-validate';
import SyncLoader from 'vue-spinner/src/SyncLoader.vue';
export default {
@@ -125,6 +126,10 @@
refreshToken() {
this.$store.dispatch('refreshToken');
},
setLang(lang) {
this.$i18n.locale=lang;
localize(lang);
},
},
mounted() {
EventBus.$on('failedLoadingRecorders', (msg) => {

View File

@@ -43,24 +43,25 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else>
<ValidationProvider :name="$t('name')" rules="required|min:3" v-slot="{ errors }" v-else slim>
<b-input-group>
<b-form-input :id="recorder.id+'_name'" name="name"
v-model="updateValues[recorder.id+'_name']"
v-validate="'required|min:3'"
v-bind:class="{'is-danger': errors.has('name'), 'is-invalid': errors.has('name')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="'Name ('+recorder.name +')'"
@blur="updateRecorder(recorder.id, 'name')"
@keyup.enter="updateRecorder(recorder.id, 'name')"
required></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('name')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'name')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
</b-input-group>
</ValidationProvider>
</h5>
<hr/>
<p class="card-text"><strong>{{ $t('Model') }}:</strong>&nbsp;
@@ -79,24 +80,25 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else size="sm">
<ValidationProvider :name="$t('network_name')" rules="required|ip_or_fqdn" v-slot="{ errors }" v-else slim>
<b-input-group size="sm">
<b-form-input name="network_name"
style="min-width: 80%;"
v-model="updateValues[recorder.id+'_network_name']"
v-validate="'required|ip_or_fqdn'"
v-bind:class="{'is-danger': errors.has('network_name'), 'is-invalid': errors.has('network_name')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="'Network name ('+recorder.network_name +')'"
@keyup.enter="updateRecorder(recorder.id, 'network_name')"></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('network_name')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'network_name')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
<span>{{ errors.first('network_name') }}</span>
<span>{{ errors[0] }}</span>
</b-input-group>
</ValidationProvider>
</p>
<p class="card-text"><strong>{{ $t('ip') }}:</strong>&nbsp;
@@ -106,24 +108,26 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else size="sm">
<ValidationProvider :name="$t('ip')" rules="ip" v-slot="{ errors }" v-else slim>
<b-input-group size="sm">
<b-form-input name="ip"
v-model="updateValues[recorder.id+'_ip']"
v-validate="'ip'"
v-bind:class="{'is-danger': errors.has('ip'), 'is-invalid': errors.has('ip')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="$t('ip address') +' ('+recorder.ip +')'"
@keyup.enter="updateRecorder(recorder.id, 'ip')"
required></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('ip')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'ip')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
<span>{{ errors[0] }}</span>
</b-input-group>
<span>{{ errors.first('ip') }}</span>
</ValidationProvider>
</p>
<p class="card-text"><strong>{{ $t('ip v6') }}:</strong>&nbsp;
@@ -133,24 +137,26 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else size="sm">
<ValidationProvider :name="$t('ip6')" rules="ip6" v-slot="{ errors }" v-else slim>
<b-input-group size="sm">
<b-form-input name="ip6"
v-model="updateValues[recorder.id+'_ip6']"
v-validate="'ip:6'"
v-bind:class="{'is-danger': errors.has('ip6'), 'is-invalid': errors.has('ip6')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="$t('ip v6 address') +' ('+recorder.ip6 +')'"
@keyup.enter="updateRecorder(recorder.id, 'ip6')"
required></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('ip6')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'ip6')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
<span>{{ errors[0] }}</span>
</b-input-group>
<span>{{ errors.first('ip6') }}</span>
</ValidationProvider>
</p>
<p class="card-text"><strong>{{ $t('ssh_port') }}:</strong>&nbsp;
@@ -160,25 +166,27 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else size="sm">
<ValidationProvider :name="$t('ssh_port')" rules="required|between:0,65535" v-slot="{ errors }" v-else slim>
<b-input-group size="sm">
<b-form-input name="ssh_port"
v-model="updateValues[recorder.id+'_ssh_port']"
v-validate="'required|between:0,65535'"
v-bind:class="{'is-danger': errors.has('ssh_port'), 'is-invalid': errors.has('ssh_port')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="'Room number ('+recorder.ssh_port +')'"
@blur="updateRecorder(recorder.id, 'ssh_port')"
@keyup.enter="updateRecorder(recorder.id, 'ssh_port')"
required></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('ssh_port')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'ssh_port')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
<span>{{ errors[0] }}</span>
</b-input-group>
<span>{{ errors.first('ssh_port') }}</span>
</ValidationProvider>
</p>
<p class="card-text"><strong>{{ $t('telnet_port') }}:</strong>&nbsp;
@@ -189,25 +197,26 @@
icon="pencil-alt"/>
</a>
</span>
<b-input-group v-else size="sm">
<ValidationProvider :name="$t('telnet_port')" rules="required|between:0,65535" v-slot="{ errors }" v-else slim>
<b-input-group size="sm">
<b-form-input name="telnet_port"
v-model="updateValues[recorder.id+'_telnet_port']"
v-validate="'required|between:0,65535'"
v-bind:class="{'is-danger': errors.has('telnet_port'), 'is-invalid': errors.has('telnet_port')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text"
:placeholder="'Room number ('+recorder.telnet_port +')'"
@blur="updateRecorder(recorder.id, 'telnet_port')"
@keyup.enter="updateRecorder(recorder.id, 'telnet_port')"
required></b-form-input>
<b-input-group-append>
<b-button :disabled="errors.has('telnet_port')"
<b-button :disabled="errors.length > 0"
@click="updateRecorder(recorder.id, 'telnet_port')"
variant="outline-success">
<font-awesome-icon icon="check"></font-awesome-icon>
</b-button>
</b-input-group-append>
<span>{{ errors[0] }}</span>
</b-input-group>
<span>{{ errors.first('telnet_port') }}</span>
</ValidationProvider>
</p>
<hr/>
@@ -363,23 +372,25 @@
<b-card-text>
<p>{{ $t('Create_a_new_recorder')}}:</p>
<!-- form starts here -->
<ValidationObserver v-slot="{ invalid }">
<form v-on:submit.prevent="saveRecorder()">
<section class="form">
<ValidationProvider :name="$t('name')" rules="required|min:3" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label required col-sm-2 col-form-label">{{ $t('name') }}</label>
<div class="col-sm-6">
<input name="name"
v-model="form.name"
v-validate="'required|min:3'"
v-bind:class="{'is-danger': errors.has('name'), 'is-invalid': errors.has('name')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('Recorder_name')"
required>
</div>
<p class="col-sm-4" v-show="errors.has('name')">
{{ errors.first('name') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<div class="form-group row">
@@ -391,93 +402,99 @@
</div>
</div>
<ValidationProvider :name="$t('network_name')" rules="required|ip_or_fqdn" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label required col-sm-2 col-form-label">{{ $t('network_name') }}</label>
<div class="col-sm-6">
<input name="network_name"
v-model="form.network_name"
v-validate="'required|ip_or_fqdn'"
v-bind:class="{'is-danger': errors.has('network_name'), 'is-invalid': errors.has('network_name')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('network_name')"
required
>
</div>
<p class="col-sm-4" v-show="errors.has('network_name')">
{{ errors.first('network_name') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('mac')" rules="mac" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('mac') }}</label>
<div class="col-sm-6">
<input name="mac"
v-validate="'mac'"
v-model="form.mac"
v-bind:class="{'is-danger': errors.has('mac'), 'is-invalid': errors.has('mac')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('Recorder') + ' ' + $t('mac')">
</div>
<p class="col-sm-4" v-show="errors.has('mac')">
{{ errors.first('mac') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('ip')" rules="ip" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('ip') }}</label>
<div class="col-sm-6">
<input name="ip"
v-validate="'ip'"
v-model="form.ip"
v-bind:class="{'is-danger': errors.has('ip'), 'is-invalid': errors.has('ip')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('Recorder') + ' ' + $t('ip')">
</div>
<p class="col-sm-4" v-show="errors.has('ip')">
{{ errors.first('ip') }}
</p>
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('ipv6')" rules="ip6" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('ipv6') }}</label>
<div class="col-sm-6">
<input name="ip6"
v-validate="'ip:6'"
v-model="form.ip6"
v-bind:class="{'is-danger': errors.has('ip6'), 'is-invalid': errors.has('ip6')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('Recorder') + ' ' + $t('ipv6')">
</div>
<p class="col-sm-4" v-show="errors.has('ip6')">
{{ errors.first('ip6') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('telnet_port')" rules="required|between:0,65535" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('telnet_port') }}</label>
<div class="col-sm-6">
<input name="telnet_port"
v-model="form.telnet_port"
v-validate="'required|between:0,65535'"
v-bind:class="{'is-danger': errors.has('telnet_port'), 'is-invalid': errors.has('telnet_port')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="number" value="22"
placeholder="Telnet Port (23)">
</div>
<p class="col-sm-4" v-show="errors.has('telnet_port')">
{{ errors.first('telnet_port') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('ssh_port')" rules="required|between:0,65535" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('ssh_port') }}</label>
<div class="col-sm-6">
<input name="ssh_port"
v-model="form.ssh_port"
v-validate="'required|between:0,65535'"
v-bind:class="{'is-danger': errors.has('ssh_port'), 'is-invalid': errors.has('ssh_port')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="number" value="23"
placeholder="SSH Port (22)">
</div>
<p class="col-sm-4" v-show="errors.has('ssh_port')">
{{ errors.first('ssh_port') }}
<p class="col-sm-4" v-show="errors.length > 0">
{{ errors[0] }}
</p>
</div>
</ValidationProvider>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('Model') }}</label>
@@ -504,12 +521,13 @@
</div>
</div>
<ValidationProvider :name="$t('username')" rules="" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('username') }}</label>
<div class="col-sm-6">
<input name="username"
v-model="form.username"
v-bind:class="{'is-danger': errors.has('username'), 'is-invalid': errors.has('username')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('username')"
>
</div>
@@ -517,13 +535,15 @@
{{$t('may_be_left_blank')}} (-> {{$t('Model')}})
</p>
</div>
</ValidationProvider>
<ValidationProvider :name="$t('password')" rules="" v-slot="{ errors }" slim>
<div class="form-group row">
<label class="label col-sm-2 col-form-label">{{ $t('password') }}</label>
<div class="col-sm-6">
<input name="password"
v-model="form.password"
v-bind:class="{'is-danger': errors.has('password'), 'is-invalid': errors.has('password')}"
v-bind:class="{'is-danger': errors.length > 0, 'is-invalid': errors.length > 0}"
class="form-control" type="text" :placeholder="$t('password')"
>
</div>
@@ -531,12 +551,13 @@
{{$t('may_be_left_blank')}} (-> {{$t('Model')}})
</p>
</div>
</ValidationProvider>
<div class="field is-grouped">
<div class="control">
<button
v-bind:disabled="errors.any()"
v-bind:disabled="invalid"
type="submit"
class="btn btn-primary">
Create recorder
@@ -546,6 +567,7 @@
</section>
</form>
</ValidationObserver>
</b-card-text>
</b-tab>
<b-tab title="Recorder model list">

View File

@@ -19,6 +19,7 @@ import VueMoment from 'vue-moment';
// following is to avoid missing type definitions
// const FlagIcon = require('vue-flag-icon');
import {library} from '@fortawesome/fontawesome-svg-core';
import {
faCoffee,
@@ -106,6 +107,7 @@ import en from 'vee-validate/dist/locale/en.json';
import de from 'vee-validate/dist/locale/de.json';
import es from 'vee-validate/dist/locale/es.json';
import * as rules from 'vee-validate/dist/rules';
import '@/validation.js';
// install rules and localization
Object.keys(rules).forEach((rule) => {

View File

@@ -1,9 +1,30 @@
import { extend } from 'vee-validate';
import { required, email } from 'vee-validate/dist/rules';
import isIp from 'is-ip';
extend('positive', value => {
return value >= 0;
});
extend('email', email);
extend('required', required);
const ip_re = new RegExp("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
const ip6_re = new RegExp("(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))")
const mac_re = new RegExp("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$");
extend('ip', value => {
return isIp.v4(value);
})
extend('ip6', value => {
return isIp.v6(value);
})
extend('ip6', value => {
return isIp.v6(value);
})
extend('mac', value => {
return mac_re.test(value);
})
//extend('email', email);
//extend('required', required);