I am using Vuetify and use its default way of adding rules to input fields.
I know there is this rule:
v => !!v
This checks if the the form input isn't empty. But how can I make it in such a way that it only accepts alphabetical letters, numbers or even apply a regex to it? I can't find anything in the docs. Can someone with any experience help me out?
So I assume that you've probably sorted this now but for anyone finding this from google etc.
To add a new rule, you need to add it to your vue component, either through an import or just adding it straight to your data object. You name it as you would any other data property and it's an array of the tests like the v => !!v one you mentioned. You then add the OR operator followed by the text to show on a failed validation.
So to add a regex that only allows letters you would have this:
data () {
return {
alphaRule: [
v => /[a-zA-Z]+$/.test(v) || 'Field must only contain letters'
]
}
}
then on your form field you would have <v-text-field :rules="alphaRule"></v-text-field>
That said, I would highly recommend adding all of your rules to a Rules.js file and binding the rules globally so that you can access them anywhere, have a centralised repository for them, and it helps keeps your code DRY too.
I have just made a big ol list of rules inspired by Laravel's Validation rules and will edit my answer to include them oncce I have finished testing them.
EDIT
Here are all the rules I'm currently using in production. Hopefully they'll help someone else! You'll need to import them into your component to use them, or you can globally include them through a vue mixin.
Related
I'm trying to use data-cy as much as I can in my code.
It's slightly tedious having to write cy.get('[data-cy=name]') all the time.
Is it possible to create a custom command that would by default try and find a data-cy first.
So if I wrote cy.get('name') it would try and find data-cy="name" on the page, if I used cy.get('.class') it would try and find a class with class on the page, if I used cy.get('#id') it would try and find an id with 'id` on the page?
Basically, I just want cy.get() to default to trying to find data-cy first and then work as it originally does if I pass in anything else to it.
It's a nifty idea, but you are leaning towards conditional testing if you try to do all-in-one.
I would have a custom command for data-cy and stick with cy.get() for the other selectors
Cypress.Commands.add('attr', { prevSubject: false }, (attr) => {
return cy.get(`[data-cy="${attr}"]`)
})
cy.attr('name')
Selecting UI elements based on an attribute, such as data-cy, is even described in the Cypress best practices section here.
There is also an example on how to create a custom command to have a common way for selecting the elements here.
The examples look like:
// cypress/support/commands.ts
Cypress.Commands.add('getBySel', (selector, ...args) => {
return cy.get(`[data-cy=${selector}]`, ...args)
})
Cypress.Commands.add('getBySelLike', (selector, ...args) => {
return cy.get(`[data-cy*=${selector}]`, ...args)
})
The first command looks for an exact data-cy attribute match. The second one looks for elements containing a data-cy like the provided argument.
If you add Cypress Testing Library to your project you get a bunch of commands around the data-testid attribute
ByTestId - find by data-testid attribute
getByTestId
queryByTestId
getAllByTestId
queryAllByTestId
findByTestId
findAllByTestId
See Cheatsheet for differences.
If you are tired of typing cy.get('[data-cy=name]'), then this profusion of selection methods may vex you even more.
The interesting part is the discussion about what selection methods are best for testing.
See Priority
Based on the Guiding Principles, your test should resemble how users interact with your code (component, page, etc.) as much as possible.
Interestingly, they place *ByTestId at the bottom of the list
The user cannot see (or hear) these, so this is only recommended for cases where you can't match by role or text or it doesn't make sense (e.g. the text is dynamic).
i make one table for with some column with nullable.
i already tried with two different query. one using
Register_member::where('passport',$passport)->orWhere('adharcardnumber',$adharcardnumber)->get();
and second DB::table type query.
$row = Register_member::where('passport',$passport)->orWhere('adharcardnumber',$adharcardnumber)->get();
if (!empty($row))
{
return response()->json(["status"=>0, "message"=>"Adharcard or Paasport number already exit."]);
}
if (empty($row))
{
Register_member::insert(['first_name'=>request('first_name'), 'middle_name'=>request('middle_name'), 'last_name'=>request('last_name'), 'adharcardnumber'=>request('adharcardnumber'), 'ocipcinumber'=>request('ocipcinumber'), 'passport'=>request('passport'), 'birthday'=>request('birthday'),
'mobilecode'=>request('mobilecode'), 'mobilenumber'=>request('mobilenumber'), 'email'=>request('email'), 'address'=>request('address'), 'landmark'=>request('landmark'), 'area'=>request('area'),
'gender'=>request('gender'), 'pincode'=>request('pincode'), 'city_name'=>request('city_name'), 'state_id'=>request('state_id'), 'country_id'=>request('country_id'), 'sampraday'=>request('sampraday'), 'other'=>request('other'), 'sms'=>request('sms')]);
return response()->json(["status"=>1, "message"=>"Member register successful."]);
}
if adharcardnumber or passport number are exists in table, then nagetive response. if in both any one in unique then, insert data in table
Let me suggest you something which I think serve you as a good solution. You can use the unique with required and regex. In this way it will use the already recommended ways of Laravel which are the best.
As an example for your adhaar card,
the validation should look like this
$request->validate([
'adhaar ' =>['required','unique:users','regex:/\d{12}/'],
]);
where adhar is the filed name where adhaar number is entered. Be sure to use validator like this use Illuminate\Support\Facades\Validator;. Also $request is the instance of the Request.
Using the required prevent empty field submission and the regex will throw an error if the pattern is not matched completely. so I think it would be a better a way to handle the scenario.
the above solution will work in both adhaar and passport. But for the passport the regex will be different though.
Please note these are all demo examples, you might need to modify it according to your needs. I use https://www.phpliveregex.com/ for regex making and checking and it is good enough.
I hope you get an idea of how to begin but if you need more information then let me know in the comments.
I'm working with a component bitrix:catalog (which is standard one) and faced an issue. I want to add some extra GET parameters to switch view mode. I think there is no need to rewrite whole component to make such switcher, so I added extra keys in result_modifier in a way similar to:
$this->__component->arResultCacheKeys = array_merge($this->__component->arResultCacheKeys, array('key1', "key2"));
Earlier in the same result_modifier I perform adding those extra keys in $arResult['key1'] etc. They seem to be correctly saved, but only for current inquiry such as ?view=list or view=card, that means only one variable value is saved and it does not react on changing of GET parameter. Is there simple and correct way to make that component to cache and to output data based on GET variable? The only idea which came to my mind is to rewrite component by adding extra parameter and checking of GET, but I think there must more simple and correct solution to make in via template. Human Readable Links are turned on. And I want to have auto-cash being turned on as well. If I turn it off it starts working as planned.
One of possible solutions is to rewrite it cache by SetTemplateCachedData but it still seems to me rough and incorrect way for such simple task.
Bitrix masters please help me to find correct solution, google can't help at the moment.
If you use standard bitrix:catalog component, you may be use standart bitrix:catalog.section. In that component.php used standart component cache.
That means you can describe additional parametr in you custom .parameters.php, and set it in bitrix:catalog.section params.
Standart component cache set cacheId based on arParams.
So you include component should look like this:
$APPLICATION->IncludeComponent(
"bitrix:catalog.section",
"",
array(
"IBLOCK_TYPE" => $arParams["IBLOCK_TYPE"],
"IBLOCK_ID" => $arParams["IBLOCK_ID"],
"ELEMENT_SORT_FIELD" => $arParams["ELEMENT_SORT_FIELD"],
"ELEMENT_SORT_ORDER" => $arParams["ELEMENT_SORT_ORDER"],
....
....
"NEW_ADDITIONAL_GET_PARAMS"=> $_GET['view']
),
$component
);
Of course better way somethink like
"NEW_ADDITIONAL_GET_PARAMS"=> (in_array($_GET['view'],array('list','card'))?$_GET['view']:'list')
But may be you need just set right catalog params: SEF_MODE SEF_FOLDER SEF_URL_TEMPLATES
Improving on this question:
Is it good practice to add own file in lib/Varien/Data/Form/Element folder
The accepted answer shows how to extend a Varien form element, but this will not work if you want to package it into a custom module.
What would be the proper method of extending the Varien form element in a module? A simple XML setting I'm hoping?
Update:
Thanks Vinai for the response. Although that does work, I was hoping to extend the form element somehow. My extension is using the base File form element to allow administrators to upload files to categories. So, I'm not directly adding the form elements to the fieldset myself.
I suppose it's possible to to check for the file input on my category block on the backend: Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes , and then change the form element if it is 'file' to 'mycompany_file' -- but this seems like a workaround.
Is there an easier way? Thanks again Vinai.
On the Varien_Data_Form instance you can specify custom element types like this:
$fieldset->addType('custom', 'Your_Module_Model_Form_Element_Custom');
Then, add your element with
$fieldset->addField('the_name', 'custom', $optionsArray);
If you are using a form without fieldsets you can do the same on the Varien_Data_Forminstance, too.
EDIT: Expand answer because of new additional details in the question.
In the class Mage_Adminhtml_Block_Widget_Form::_setFieldset() there is the following code:
$rendererClass = $attribute->getFrontend()->getInputRendererClass();
if (!empty($rendererClass)) {
$fieldType = $inputType . '_' . $attribute->getAttributeCode();
$fieldset->addType($fieldType, $rendererClass);
}
Because of this the attribute frontend_input_renderer on the attributes can be used to specify custom element classes.
This property can be found in the table catalog_eav_attribute, and luckily enough it isn't set for any of the category image attributes.
Given this, there are several ways to apply customizaton.
One option is to simply set the element class in the table using an upgrade script.
Another would be using an observer for the eav_entity_attribute_load_after event and setting the input renderer on the fly if the entity_type_id and the input type matches.
So it is a little more involved then just regular class rewrites in Magento, but it is quite possible.
You don't necessarily need to have a file in the lib/Varien/ directory in order to extend it. If you needed to add an element to that collection, you should be able to extend one of the Elements in your app/code/local module. The answer to the question you referenced seems to also indicate this is the case. I would create your custom field, extending its highest-level function set (i.e., lib/Varien/Data/Form/Element/File.php).
If you want to override the Mage_Adminhtml_Block_Catalog_Category_Tab_Attributes block, then you should extend that block in your module and then reference the new one. You may wish to extend the block using an event observer rather than an XML rewrite, for compatibility purposes.
which is the preferred approach in sanitizing inputs coming from the user?
thank you!
I think whitelisting is the desired approach, however I never met a real whitelist HTML form validation. For example here is a symfony 1.x form with validation from the documentation:
class ContactForm extends sfForm
{
protected static $subjects = array('Subject A', 'Subject B', 'Subject C');
public function configure()
{
$this->setWidgets(array(
'name' => new sfWidgetFormInput(),
'email' => new sfWidgetFormInput(),
'subject' => new sfWidgetFormSelect(array('choices' => self::$subjects)),
'message' => new sfWidgetFormTextarea(),
));
$this->widgetSchema->setNameFormat('contact[%s]');
$this->setValidators(array(
'name' => new sfValidatorString(array('required' => false)),
'email' => new sfValidatorEmail(),
'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
'message' => new sfValidatorString(array('min_length' => 4)),
));
}
}
What you cannot see, that it accepts new inputs without validation settings and it does not check the presence of inputs which are not registered in the form. So this is a blacklist input validation. By whitelist you would define an input validator first, and only after that bind an input field to that validator. By a blacklist approach like this, it is easy to forget to add a validator to an input, and it works perfectly without that, so you would not notice the vulnerability, only when it is too late...
A hypothetical whitelist approach would look like something like this:
class ContactController {
/**
* #input("name", type = "string", singleLine = true, required = false)
* #input("email", type = "email")
* #input("subject", type = "string", alternatives = ['Subject A', 'Subject B', 'Subject C'])
* #input("message", type = "string", range = [4,])
*/
public function post(Inputs $inputs){
//automatically validates inputs
//throws error when an input is not on the list
//throws error when an input has invalid value
}
}
/**
* #controller(ContactController)
* #method(post)
*/
class ContactForm extends sfFormX {
public function configure(InputsMeta $inputs)
{
//automatically binds the form to the input list of the #controller.#method
//throws error when the #controller.#method.#input is not defined for a widget
$this->addWidgets(
new sfWidgetFormInput($inputs->name),
new sfWidgetFormInput($inputs->email),
new sfWidgetFormSelect($inputs->subject),
new sfWidgetFormTextarea($inputs->message)
);
$this->widgetSchema->setNameFormat('contact[%s]');
}
}
The best approach is to either use stored procedures or parameterized queries. White listing is an additional technique that is ok to prevent any injections before they reach the server, but should not be used as your primary defense. Black listing is usually a bad idea because it's usually impossible to filter out all malicious inputs.
BTW, this answer is considering you mean sanitizing as in preventing sql injection.
WL is a best practice against BL whenever it is practicable.
The reason is simple: you can't be reasonably safe enumerating what it is not permitted, an attacker could always find a way you did not think about. If you can, say what is allowed for sure, it is simpler and much much safer !
Let me explain your question with few more question and answer.
Blacklist VS Whitelist restriction
i. A Blacklist XSS and SQL Injection handling verifies a desired input against a list of negative input's. Basically one would compile a list of all the negative or bad conditions, and verifies that the input received is not one among the bad or negative conditions.
ii. A Whitelist XSS and SQL Injection handling verifies a desired input against a list of possible correct input's. To do this one would compile a list of all the good/positive input values/conditions, and verifies that the input received is one among the correct conditions.
Which one is better to have?
i. An attacker will use any possible means to gain access to your application. This includes trying all sort of negative or bad conditions, various encoding methods, and appending malicious input data to valid data. Do you think you can think of every possible bad permutation that could occur?
ii. A Whitelist is the best way to validate input. You will know exacty what is desired and that there is not any bad types accepted. Typically the best way to create a whitelist is with the use of regular expression's. Using regular expressions is a great way to abstract the whitelisting, instead of manually listing every possible correct value.
Build a good regular expression. Just because you are using a regular expression does not mean bad input will not be accepted. Make sure you test your regular expression and that invalid input cannot be accepted by your regular expression.
Personally, I gauge the number of allowed or disallowed characters and go from there. If there are more allowed chars than disallowed, then blacklist. Else whitelist. I don't believe that there is any 'standard' that says you should do it one way or the other.
BTW, this answer is assuming you want to limit inputs into form fields such as phone numbers or names :) #posterBelow
As a general rule it's best to use whitelist validation since it's easier to accept only characters you know should go there, for example if you have a field where the user inputs his/her phone number you could just do a regex and check that the values received are only numbers, drop everything else and just store the numbers. Note that you should proceed to validate the resulting numbers as well. Blacklist validation is weaker because a skilled attacker could evade your validation functions or send values that your function did not expect, from OWASP "Sanitize with Blacklist":
Eliminate or translate characters (such as to HTML entities or to remove quotes) in an effort to make the input "safe". Like blacklists, this approach requires maintenance and is usually incomplete. As most fields have a particular grammar, it is simpler, faster, and more secure to simply validate a single correct positive test than to try to include complex and slow sanitization routines for all current and future attacks.
Realize that this validation is just a first front defense against attacks. For XSS you should always "Escape" your output so you can print any character's needed but they are escaped meaning that they are changed to their HTML entity and thus the browser knows it's data and not something that the parser should interpret thus effectively shutting down all XSS attacks. For SQL injections escape all data before storing it, try to never use dynamic queries as they are the easiest type of query to exploit. Try to use parameterized store procedures. Also remember to use connections relevant to what the connection has to do. If the connection only needs to read data, create a db account with only "Read" privileges this depends mostly on the roles of the users. For more information please check the links from where this information was extracted from:
Data Validation OWASP
Guide to SQL Injection OWASP
The answer generally is, it depends.
For inputs with clearly defined parameters (say the equivalent of a dropdown menu), I would whitelist the options and ignore anything that wasn't one of those.
For free-text inputs, it's significantly more difficult. I subscribe to the school of thought that you should just filter it as best you can so it's as safe as possible (escape HTML, etc). Some other suggestions would be to specifically disallow any invalid input - however, while this might protect against attacks, it might also affect usability for genuine users.
I think it's just a case of finding the blend that works for you. I can't think of any one solution that would work for all possibilities. Mostly it depends on your userbase.