Skip to content

Commit cff6ec1

Browse files
authored
Merge pull request #60 from devforth/validation-backend-check
fix: add validation backend check
2 parents 7089d26 + 0df1c0f commit cff6ec1

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

adminforth/documentation/docs/tutorial/03-Customization/13-standardPagesTuning.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,32 @@ export default {
343343

344344
### Validation
345345

346-
[Documentation in progress]
346+
In cases when column values must follow certain format, you can add `validation` to it.
347+
`validation` is an array of rules, each containing `regExp` that defines a format for a value and `message` that will be displayed in case when entered value does not pass the check.
348+
349+
```typescript title="./resources/users.ts"
350+
export default {
351+
name: 'users',
352+
columns: [
353+
...
354+
{
355+
name: 'email',
356+
required: true,
357+
isUnique: true,
358+
validation: [
359+
{
360+
regExp: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
361+
message: 'Email is not valid, must be in format [email protected]',
362+
},
363+
],
364+
},
365+
],
366+
},
367+
...
368+
],
369+
```
370+
371+
> `validation` checks are enforced both on frontend and backend.
347372
348373
### Foreign resources
349374

adminforth/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,36 @@ class AdminForth implements IAdminForth {
5353
return await AdminForthAuth.generatePasswordHash(password);
5454
},
5555

56+
applyRegexValidation(value, validation) {
57+
if (validation?.length) {
58+
const validationArray = validation;
59+
for (let i = 0; i < validationArray.length; i++) {
60+
if (validationArray[i].regExp) {
61+
let flags = '';
62+
if (validationArray[i].caseSensitive) {
63+
flags += 'i';
64+
}
65+
if (validationArray[i].multiline) {
66+
flags += 'm';
67+
}
68+
if (validationArray[i].global) {
69+
flags += 'g';
70+
}
71+
72+
const regExp = new RegExp(validationArray[i].regExp, flags);
73+
if (value === undefined || value === null) {
74+
value = '';
75+
}
76+
let valueS = `${value}`;
77+
78+
if (!regExp.test(valueS)) {
79+
return validationArray[i].message;
80+
}
81+
}
82+
}
83+
}
84+
},
85+
5686
PASSWORD_VALIDATORS: {
5787
UP_LOW_NUM_SPECIAL: {
5888
regExp: '^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#\\$%\\^&\\*\\(\\)\\-_=\\+\\[\\]\\{\\}\\|;:\',\\.<>\\/\\?]).+$',
@@ -320,6 +350,14 @@ class AdminForth implements IAdminForth {
320350
{ resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
321351
): Promise<{ error?: string, createdRecord?: any }> {
322352

353+
// check if record with validation is valid
354+
for (const column of resource.columns.filter((col) => col.name in record && col.validation)) {
355+
const error = AdminForth.Utils.applyRegexValidation(record[column.name], column.validation);
356+
if (error) {
357+
return { error };
358+
}
359+
}
360+
323361
// check if record with minValue or maxValue is within limits
324362
for (const column of resource.columns.filter((col) => col.name in record
325363
&& ['integer', 'decimal', 'float'].includes(col.type)
@@ -397,6 +435,14 @@ class AdminForth implements IAdminForth {
397435
{ resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
398436
): Promise<{ error?: string }> {
399437

438+
// check if record with validation is valid
439+
for (const column of resource.columns.filter((col) => col.name in record && col.validation)) {
440+
const error = AdminForth.Utils.applyRegexValidation(record[column.name], column.validation);
441+
if (error) {
442+
return { error };
443+
}
444+
}
445+
400446
// check if record with minValue or maxValue is within limits
401447
for (const column of resource.columns.filter((col) => col.name in record
402448
&& ['integer', 'decimal', 'float'].includes(col.type)

0 commit comments

Comments
 (0)