feat(livechat): add validation for custom fields

pull/15840/head
Anton Kazarinov 6 years ago
parent cfb3c89fa2
commit 8709da5b02
  1. 6
      app/livechat/client/views/app/livechatCustomFieldForm.html
  2. 2
      app/livechat/client/views/app/livechatCustomFieldForm.js
  3. 5
      app/livechat/client/views/app/tabbar/visitorEdit.js
  4. 26
      app/livechat/server/lib/Livechat.js
  5. 5
      app/livechat/server/methods/saveCustomField.js
  6. 22
      app/models/server/models/LivechatRooms.js
  7. 4
      packages/rocketchat-i18n/i18n/en.i18n.json

@ -34,6 +34,12 @@
</select>
</div>
</div>
<div class="input-line">
<label>{{_ "Regexp_validation"}}</label>
<div>
<input type="text" class="rc-input__element" name="regexp" value="{{customField.regexp}}" placeholder="{{_ "Regexp_validation"}}" />
</div>
</div>
</fieldset>
<div class="rc-button__group submit">
<button class="rc-button back" type="button"><i class="icon-left-big"></i><span>{{_ "Back"}}</span></button>

@ -24,6 +24,7 @@ Template.livechatCustomFieldForm.events({
const label = instance.$('input[name=label]').val();
const scope = instance.$('select[name=scope]').val();
const visibility = instance.$('select[name=visibility]').val();
const regexp = instance.$('input[name=regexp]').val();
if (!/^[0-9a-zA-Z-_]+$/.test(field)) {
return toastr.error(t('error-invalid-custom-field-name'));
@ -41,6 +42,7 @@ Template.livechatCustomFieldForm.events({
label,
scope: scope.trim(),
visibility: visibility.trim(),
regexp: regexp.trim(),
};
Meteor.call('livechat:saveCustomField', _id, customFieldData, function(error) {

@ -176,6 +176,7 @@ Template.visitorEdit.events({
toastr.error(t(err.error));
} else {
toastr.success(t('Saved'));
this.save();
}
});
},
@ -231,10 +232,6 @@ Template.visitorEdit.events({
}
},
'click .save'() {
this.save();
},
'click .cancel'() {
this.cancel();
},

@ -289,7 +289,24 @@ export const Livechat = {
updateData.phone = phone;
}
if (livechatData) {
updateData.livechatData = livechatData;
updateData.livechatData = {};
const fields = LivechatCustomField.find({ scope: 'visitor' });
fields.forEach((field) => {
if (!livechatData.hasOwnProperty(field._id)) {
return;
}
const value = s.trim(livechatData[field._id]);
if (value === '') {
return;
}
if (field.regexp !== undefined && field.regexp !== '') {
const regexp = new RegExp(field.regexp);
if (!regexp.test(value)) {
throw new Meteor.Error(TAPi18n.__('error-invalid-custom-field-value', { field: field.label }));
}
}
updateData.livechatData[field._id] = value;
});
}
const ret = LivechatVisitors.saveGuestById(_id, updateData);
@ -367,6 +384,13 @@ export const Livechat = {
throw new Meteor.Error('invalid-custom-field');
}
if (customField.regexp !== undefined && customField.regexp !== '') {
const regexp = new RegExp(customField.regexp);
if (!regexp.test(value)) {
throw new Meteor.Error(TAPi18n.__('error-invalid-custom-field-value', { field: key }));
}
}
if (customField.scope === 'room') {
return LivechatRooms.updateDataByToken(token, key, value, overwrite);
}

@ -14,7 +14,7 @@ Meteor.methods({
check(_id, String);
}
check(customFieldData, Match.ObjectIncluding({ field: String, label: String, scope: String, visibility: String }));
check(customFieldData, Match.ObjectIncluding({ field: String, label: String, scope: String, visibility: String, regexp: String }));
if (!/^[0-9a-zA-Z-_]+$/.test(customFieldData.field)) {
throw new Meteor.Error('error-invalid-custom-field-nmae', 'Invalid custom field name. Use only letters, numbers, hyphens and underscores.', { method: 'livechat:saveCustomField' });
@ -26,7 +26,6 @@ Meteor.methods({
throw new Meteor.Error('error-invalid-custom-field', 'Custom Field Not found', { method: 'livechat:saveCustomField' });
}
}
return LivechatCustomField.createOrUpdateCustomField(_id, customFieldData.field, customFieldData.label, customFieldData.scope, customFieldData.visibility);
return LivechatCustomField.createOrUpdateCustomField(_id, customFieldData.field, customFieldData.label, customFieldData.scope, customFieldData.visibility, { regexp: customFieldData.regexp });
},
});

@ -1,10 +1,12 @@
import { Meteor } from 'meteor/meteor';
import s from 'underscore.string';
import _ from 'underscore';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import { Base } from './_Base';
import Rooms from './Rooms';
import Settings from './Settings';
import { LivechatCustomField } from '../index';
export class LivechatRooms extends Base {
constructor(...args) {
@ -88,11 +90,23 @@ export class LivechatRooms extends Base {
if (livechatData) {
setData.livechatData = {};
for (const field in livechatData) {
if (livechatData.hasOwnProperty(field) && !_.isEmpty(s.trim(livechatData[field]))) {
setData.livechatData[field] = s.trim(livechatData[field]);
const fields = LivechatCustomField.find({ scope: 'room' });
fields.forEach((field) => {
if (!livechatData.hasOwnProperty(field._id)) {
return;
}
}
const value = s.trim(livechatData[field._id]);
if (value === '') {
return;
}
if (field.regex !== undefined && field.regex !== '') {
const regexp = new RegExp(field.regex);
if (!regexp.test(value)) {
throw new Meteor.Error(TAPi18n.__('error-invalid-custom-field-value', { field: field.label }));
}
}
setData.livechatData[field._id] = value;
});
}
const update = {};

@ -1300,6 +1300,7 @@
"error-invalid-channel-start-with-chars": "Invalid channel. Start with @ or #",
"error-invalid-custom-field": "Invalid custom field",
"error-invalid-custom-field-name": "Invalid custom field name. Use only letters, numbers, hyphens and underscores.",
"error-invalid-custom-field-value": "Invalid value for __field__ field",
"error-invalid-date": "Invalid date provided.",
"error-invalid-description": "Invalid description",
"error-invalid-domain": "Invalid domain",
@ -2614,6 +2615,7 @@
"Refresh_oauth_services": "Refresh OAuth Services",
"Refresh_your_page_after_install_to_enable_screen_sharing": "Refresh your page after install to enable screen sharing",
"Regenerate_codes": "Regenerate codes",
"Regexp_validation": "Validation by RegExp",
"Register": "Register a new account",
"Register_Server": "Register Server",
"Register_Server_Info": "Use the preconfigured gateways and proxies provided by Rocket.Chat Technologies Corp.",
@ -3538,4 +3540,4 @@
"Your_server_link": "Your server link",
"Your_temporary_password_is_password": "Your temporary password is <strong>[password]</strong>.",
"Your_workspace_is_ready": "Your workspace is ready to use 🎉"
}
}

Loading…
Cancel
Save