Batch of fixes (#1667)

* Fixed validation pattern, register form refactoring

* Fixed snapToGrid for resize #1590

* Changed name validation pattern #1599

* Updated version

* Updated changelog
main
Boris Sekachev 6 years ago committed by GitHub
parent 06dd90974a
commit 5789199fd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed dataset filter item representation for imageless dataset items (https://github.com/opencv/cvat/pull/1593) - Fixed dataset filter item representation for imageless dataset items (https://github.com/opencv/cvat/pull/1593)
- Fixed interpreter crash when trying to import `tensorflow` with no AVX instructions available (https://github.com/opencv/cvat/pull/1567) - Fixed interpreter crash when trying to import `tensorflow` with no AVX instructions available (https://github.com/opencv/cvat/pull/1567)
- Kibana wrong working time calculation with new annotation UI use (<https://github.com/opencv/cvat/pull/1654>) - Kibana wrong working time calculation with new annotation UI use (<https://github.com/opencv/cvat/pull/1654>)
- Wrong rexex for account name validation (<https://github.com/opencv/cvat/pull/1667>)
- Wrong description on register view for the username field (<https://github.com/opencv/cvat/pull/1667>)
- Wrong resolution for resizing a shape (<https://github.com/opencv/cvat/pull/1667>)
### Security ### Security
- SQL injection in Django `CVE-2020-9402` (https://github.com/opencv/cvat/pull/1657) - SQL injection in Django `CVE-2020-9402` (https://github.com/opencv/cvat/pull/1657)

@ -1401,7 +1401,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
let shapeSizeElement: ShapeSizeElement | null = null; let shapeSizeElement: ShapeSizeElement | null = null;
let resized = false; let resized = false;
(shape as any).resize().on('resizestart', (): void => { (shape as any).resize({
snapToGrid: 0.1,
}).on('resizestart', (): void => {
this.mode = Mode.RESIZE; this.mode = Mode.RESIZE;
if (state.shapeType === 'rectangle') { if (state.shapeType === 'rectangle') {
shapeSizeElement = displayShapeSize(this.adoptedContent, this.adoptedText); shapeSizeElement = displayShapeSize(this.adoptedContent, this.adoptedText);

@ -1,6 +1,6 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.2.1", "version": "1.2.2",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,6 +1,6 @@
{ {
"name": "cvat-ui", "name": "cvat-ui",
"version": "1.2.1", "version": "1.2.2",
"description": "CVAT single-page application", "description": "CVAT single-page application",
"main": "src/index.tsx", "main": "src/index.tsx",
"scripts": { "scripts": {

@ -11,7 +11,7 @@ import Checkbox from 'antd/lib/checkbox';
import patterns from 'utils/validation-patterns'; import patterns from 'utils/validation-patterns';
import { UserAgreement } from 'reducers/interfaces' import { UserAgreement } from 'reducers/interfaces';
import { Row, Col } from 'antd/lib/grid'; import { Row, Col } from 'antd/lib/grid';
export interface UserConfirmation { export interface UserConfirmation {
@ -31,7 +31,7 @@ export interface RegisterData {
type RegisterFormProps = { type RegisterFormProps = {
fetching: boolean; fetching: boolean;
userAgreements: UserAgreement[], userAgreements: UserAgreement[];
onSubmit(registerData: RegisterData): void; onSubmit(registerData: RegisterData): void;
} & FormComponentProps; } & FormComponentProps;
@ -83,7 +83,7 @@ class RegisterFormComponent extends React.PureComponent<RegisterFormProps> {
private validateAgrement = (agreement: any, value: any, callback: any): void => { private validateAgrement = (agreement: any, value: any, callback: any): void => {
const { userAgreements } = this.props; const { userAgreements } = this.props;
let isValid: boolean = true; let isValid = true;
for (const userAgreement of userAgreements) { for (const userAgreement of userAgreements) {
if (agreement.field === userAgreement.name if (agreement.field === userAgreement.name
&& userAgreement.required && !value) { && userAgreement.required && !value) {
@ -107,18 +107,20 @@ class RegisterFormComponent extends React.PureComponent<RegisterFormProps> {
form.validateFields((error, values): void => { form.validateFields((error, values): void => {
if (!error) { if (!error) {
values.confirmations = [] const validatedFields = {
...values,
confirmations: [],
};
for (const userAgreement of userAgreements) { for (const userAgreement of userAgreements) {
validatedFields.confirmations.push({
values.confirmations.push({
name: userAgreement.name, name: userAgreement.name,
value: values[userAgreement.name] value: validatedFields[userAgreement.name],
}); });
delete values[userAgreement.name]; delete validatedFields[userAgreement.name];
} }
onSubmit(values); onSubmit(validatedFields);
} }
}); });
}; };
@ -255,8 +257,7 @@ class RegisterFormComponent extends React.PureComponent<RegisterFormProps> {
private renderUserAgreements(): JSX.Element[] { private renderUserAgreements(): JSX.Element[] {
const { form, userAgreements } = this.props; const { form, userAgreements } = this.props;
const getUserAgreementsElements = () => const getUserAgreementsElements = (): JSX.Element[] => {
{
const agreementsList: JSX.Element[] = []; const agreementsList: JSX.Element[] = [];
for (const userAgreement of userAgreements) { for (const userAgreement of userAgreements) {
agreementsList.push( agreementsList.push(
@ -269,18 +270,24 @@ class RegisterFormComponent extends React.PureComponent<RegisterFormProps> {
message: 'You must accept to continue!', message: 'You must accept to continue!',
}, { }, {
validator: this.validateAgrement, validator: this.validateAgrement,
}] }],
})( })(
<Checkbox> <Checkbox>
I read and accept the <a rel='noopener noreferrer' target='_blank' I read and accept the
href={ userAgreement.url }>{ userAgreement.displayText }</a> <a
</Checkbox> rel='noopener noreferrer'
target='_blank'
href={userAgreement.url}
>
{userAgreement.displayText}
</a>
</Checkbox>,
)} )}
</Form.Item> </Form.Item>,
); );
} }
return agreementsList; return agreementsList;
} };
return getUserAgreementsElements(); return getUserAgreementsElements();
} }

@ -26,7 +26,7 @@ const validationPatterns = {
validateUsernameLength: { validateUsernameLength: {
pattern: /(?=.{5,})/, pattern: /(?=.{5,})/,
message: 'Username must have at least 8 characters', message: 'Username must have at least 5 characters',
}, },
validateUsernameCharacters: { validateUsernameCharacters: {
@ -34,9 +34,19 @@ const validationPatterns = {
message: 'Only characters (a-z), (A-Z), (0-9), -, _ are available', message: 'Only characters (a-z), (A-Z), (0-9), -, _ are available',
}, },
/*
\p{Pd} - dash connectors
\p{Pc} - connector punctuations
\p{Cf} - invisible formatting indicator
\p{L} - any alphabetic character
Useful links:
https://stackoverflow.com/questions/4323386/multi-language-input-validation-with-utf-8-encoding
https://stackoverflow.com/questions/280712/javascript-unicode-regexes
https://stackoverflow.com/questions/6377407/how-to-validate-both-chinese-unicode-and-english-name
*/
validateName: { validateName: {
// eslint-disable-next-line // eslint-disable-next-line
pattern: /^[a-zA-Z]{2,}(([',. -][a-zA-Z ])?[a-zA-Z]*)*$/, pattern: /^(\p{L}|\p{Pd}|\p{Cf}|\p{Pc}|['\s]){2,}$/gu,
message: 'Invalid name', message: 'Invalid name',
}, },

Loading…
Cancel
Save