@cloud-ru/uikit-product-claudia 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/cjs/components/SshField/SshField.js +33 -46
- package/dist/cjs/components/SshField/components/MobileFieldAi/MobileFieldAi.d.ts +3 -0
- package/dist/cjs/components/SshField/components/MobileFieldAi/MobileFieldAi.js +2 -2
- package/dist/cjs/components/SshField/helperComponents/CheckItem/CheckItem.d.ts +6 -0
- package/dist/cjs/components/SshField/helperComponents/CheckItem/CheckItem.js +13 -0
- package/dist/cjs/components/SshField/helperComponents/CheckItem/index.d.ts +1 -0
- package/dist/cjs/components/SshField/helperComponents/CheckItem/index.js +17 -0
- package/dist/cjs/components/SshField/helperComponents/CheckItem/styles.module.css +25 -0
- package/dist/cjs/components/SshField/helperComponents/DropZoneContent/styles.module.css +1 -1
- package/dist/cjs/components/SshField/helperComponents/SshValidation/SshValidation.d.ts +6 -0
- package/dist/cjs/components/SshField/helperComponents/SshValidation/SshValidation.js +16 -0
- package/dist/cjs/components/SshField/helperComponents/SshValidation/index.d.ts +1 -0
- package/dist/cjs/components/SshField/helperComponents/SshValidation/index.js +17 -0
- package/dist/cjs/components/SshField/helperComponents/SshValidation/styles.module.css +35 -0
- package/dist/cjs/components/SshField/helperComponents/WithSshValidation/WithSshValidation.d.ts +8 -0
- package/dist/cjs/components/SshField/helperComponents/WithSshValidation/WithSshValidation.js +19 -0
- package/dist/cjs/components/SshField/helperComponents/WithSshValidation/index.d.ts +1 -0
- package/dist/cjs/components/SshField/helperComponents/WithSshValidation/index.js +17 -0
- package/dist/cjs/components/SshField/helperComponents/WithSshValidation/styles.module.css +5 -0
- package/dist/cjs/components/SshField/types.d.ts +12 -0
- package/dist/cjs/components/SshField/types.js +2 -0
- package/dist/cjs/components/SshField/utils/readFileContent.d.ts +6 -1
- package/dist/cjs/components/SshField/utils/readFileContent.js +6 -11
- package/dist/cjs/components/SshField/utils/validateSSHKey.d.ts +9 -3
- package/dist/cjs/components/SshField/utils/validateSSHKey.js +56 -59
- package/dist/esm/components/SshField/SshField.js +34 -47
- package/dist/esm/components/SshField/components/MobileFieldAi/MobileFieldAi.d.ts +3 -0
- package/dist/esm/components/SshField/components/MobileFieldAi/MobileFieldAi.js +2 -2
- package/dist/esm/components/SshField/helperComponents/CheckItem/CheckItem.d.ts +6 -0
- package/dist/esm/components/SshField/helperComponents/CheckItem/CheckItem.js +7 -0
- package/dist/esm/components/SshField/helperComponents/CheckItem/index.d.ts +1 -0
- package/dist/esm/components/SshField/helperComponents/CheckItem/index.js +1 -0
- package/dist/esm/components/SshField/helperComponents/CheckItem/styles.module.css +25 -0
- package/dist/esm/components/SshField/helperComponents/DropZoneContent/styles.module.css +1 -1
- package/dist/esm/components/SshField/helperComponents/SshValidation/SshValidation.d.ts +6 -0
- package/dist/esm/components/SshField/helperComponents/SshValidation/SshValidation.js +10 -0
- package/dist/esm/components/SshField/helperComponents/SshValidation/index.d.ts +1 -0
- package/dist/esm/components/SshField/helperComponents/SshValidation/index.js +1 -0
- package/dist/esm/components/SshField/helperComponents/SshValidation/styles.module.css +35 -0
- package/dist/esm/components/SshField/helperComponents/WithSshValidation/WithSshValidation.d.ts +8 -0
- package/dist/esm/components/SshField/helperComponents/WithSshValidation/WithSshValidation.js +13 -0
- package/dist/esm/components/SshField/helperComponents/WithSshValidation/index.d.ts +1 -0
- package/dist/esm/components/SshField/helperComponents/WithSshValidation/index.js +1 -0
- package/dist/esm/components/SshField/helperComponents/WithSshValidation/styles.module.css +5 -0
- package/dist/esm/components/SshField/types.d.ts +12 -0
- package/dist/esm/components/SshField/types.js +1 -0
- package/dist/esm/components/SshField/utils/readFileContent.d.ts +6 -1
- package/dist/esm/components/SshField/utils/readFileContent.js +6 -11
- package/dist/esm/components/SshField/utils/validateSSHKey.d.ts +9 -3
- package/dist/esm/components/SshField/utils/validateSSHKey.js +53 -55
- package/package.json +6 -5
- package/src/components/SshField/SshField.tsx +120 -121
- package/src/components/SshField/components/MobileFieldAi/MobileFieldAi.tsx +6 -5
- package/src/components/SshField/helperComponents/CheckItem/CheckItem.tsx +23 -0
- package/src/components/SshField/helperComponents/CheckItem/index.ts +1 -0
- package/src/components/SshField/helperComponents/CheckItem/styles.module.scss +31 -0
- package/src/components/SshField/helperComponents/DropZoneContent/styles.module.scss +1 -1
- package/src/components/SshField/helperComponents/SshValidation/SshValidation.tsx +36 -0
- package/src/components/SshField/helperComponents/SshValidation/index.ts +1 -0
- package/src/components/SshField/helperComponents/SshValidation/styles.module.scss +31 -0
- package/src/components/SshField/helperComponents/WithSshValidation/WithSshValidation.tsx +43 -0
- package/src/components/SshField/helperComponents/WithSshValidation/index.ts +1 -0
- package/src/components/SshField/helperComponents/WithSshValidation/styles.module.scss +7 -0
- package/src/components/SshField/types.ts +13 -0
- package/src/components/SshField/utils/readFileContent.ts +12 -11
- package/src/components/SshField/utils/validateSSHKey.ts +60 -68
- package/dist/cjs/components/SshField/utils/handleFileError.d.ts +0 -2
- package/dist/cjs/components/SshField/utils/handleFileError.js +0 -32
- package/dist/esm/components/SshField/utils/handleFileError.d.ts +0 -2
- package/dist/esm/components/SshField/utils/handleFileError.js +0 -28
- package/src/components/SshField/utils/handleFileError.ts +0 -41
|
@@ -1,84 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
const trimmedContent = content.trim();
|
|
1
|
+
const MAX_FILE_SIZE = 10 * 1024; // 10KB по умолчанию
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
const SSH_KEY_BEGIN_PATTERN = [
|
|
4
|
+
/^-----BEGIN (?:RSA|DSA|EC|OPENSSH) PRIVATE KEY-----/,
|
|
5
|
+
/^-----BEGIN.*PRIVATE KEY-----/,
|
|
6
|
+
/^-----BEGIN.*CERTIFICATE-----/,
|
|
7
|
+
];
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const SSH_KEY_END_PATTERN = [
|
|
10
|
+
/-----END (?:RSA|DSA|EC|OPENSSH) PRIVATE KEY-----/,
|
|
11
|
+
/-----END.*PRIVATE KEY-----/,
|
|
12
|
+
/-----END.*CERTIFICATE-----/,
|
|
13
|
+
];
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
// Если больше 10% бинарных символов
|
|
16
|
-
throw new Error('INVALID_SSH_KEY: Файл содержит бинарные данные, а не текстовый SSH ключ');
|
|
17
|
-
}
|
|
15
|
+
const checkIsFileSizeError = (file: File) => file.size > MAX_FILE_SIZE;
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/^ssh-(rsa|dsa|ecdsa|ed25519)/,
|
|
23
|
-
/^ecdsa-sha2-nistp/,
|
|
24
|
-
/^-----BEGIN.*PRIVATE KEY-----/,
|
|
25
|
-
/^-----BEGIN.*CERTIFICATE-----/,
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
const isValidSSHKey = sshKeyPatterns.some(pattern => pattern.test(trimmedContent));
|
|
29
|
-
|
|
30
|
-
if (!isValidSSHKey) {
|
|
31
|
-
throw new Error(
|
|
32
|
-
'INVALID_SSH_KEY: Файл не содержит валидный SSH ключ. Поддерживаются: RSA, DSA, ECDSA, Ed25519 ключи и сертификаты',
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
17
|
+
function getFileExtension(filename: string) {
|
|
18
|
+
return filename.includes('.') ? filename.split('.').pop() : '';
|
|
19
|
+
}
|
|
36
20
|
|
|
37
|
-
const
|
|
38
|
-
const MAX_FILE_SIZE = 10 * 1024; // 10KB по умолчанию
|
|
21
|
+
const checkIsFileTypeError = (file: File) => Boolean(getFileExtension(file.name));
|
|
39
22
|
|
|
40
|
-
const
|
|
41
|
-
|
|
23
|
+
export const validateFileErrors = (file: File) => ({
|
|
24
|
+
fileSize: checkIsFileSizeError(file),
|
|
25
|
+
fileType: checkIsFileTypeError(file),
|
|
26
|
+
});
|
|
42
27
|
|
|
43
|
-
|
|
44
|
-
if (lastDotIndex <= 0) {
|
|
45
|
-
return '';
|
|
46
|
-
}
|
|
28
|
+
const checkIsEmptyContent = (value: string) => !value.trim().length;
|
|
47
29
|
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
const checkIsBinaryCharsInContent = (value: string) => {
|
|
31
|
+
const binaryChars = value
|
|
32
|
+
.split('')
|
|
33
|
+
.filter(char => char.charCodeAt(0) < 32 && !['\n', '\r', '\t'].includes(char)).length;
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
return binaryChars > value.length * 0.1;
|
|
36
|
+
};
|
|
52
37
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
const removePEMBoundaries = (sshFileContent: string) => {
|
|
39
|
+
let replacedContent = sshFileContent.trim().replaceAll('\n', '');
|
|
40
|
+
let isBeginPartExist = false;
|
|
41
|
+
let isEndPartExist = false;
|
|
42
|
+
|
|
43
|
+
SSH_KEY_BEGIN_PATTERN.forEach(pattern => {
|
|
44
|
+
if (pattern.test(replacedContent)) {
|
|
45
|
+
isBeginPartExist = true;
|
|
46
|
+
replacedContent = replacedContent.replace(new RegExp(pattern, 'g'), '');
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
SSH_KEY_END_PATTERN.forEach(pattern => {
|
|
51
|
+
if (pattern.test(replacedContent)) {
|
|
52
|
+
isEndPartExist = true;
|
|
53
|
+
replacedContent = replacedContent.replace(new RegExp(pattern, 'g'), '');
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return { isError: !(isBeginPartExist && isEndPartExist), content: replacedContent };
|
|
58
|
+
};
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
allowedMime => mimeType.includes(allowedMime) || allowedMime.includes(mimeType),
|
|
60
|
-
);
|
|
60
|
+
const checkIsSshKeyError = (value: string) => {
|
|
61
|
+
const { isError, content: base64content } = removePEMBoundaries(value);
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
throw new Error(
|
|
65
|
-
`INVALID_MIME_TYPE: Неподходящий тип файла. MIME: ${mimeType}, расширение: ${fileExtension || 'нет'}. ` +
|
|
66
|
-
`Разрешенные MIME types: ${DEFAULT_ALLOWED_MIME_TYPES.join(', ')}, `,
|
|
67
|
-
);
|
|
63
|
+
if (isError) {
|
|
64
|
+
return true;
|
|
68
65
|
}
|
|
69
|
-
};
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
if (file.size > MAX_FILE_SIZE) {
|
|
73
|
-
throw new Error(
|
|
74
|
-
`FILE_TOO_LARGE: Файл слишком большой. Размер: ${(file.size / 1024).toFixed(2)}KB, ` +
|
|
75
|
-
`максимальный: ${MAX_FILE_SIZE / 1024}KB`,
|
|
76
|
-
);
|
|
77
|
-
}
|
|
67
|
+
const base64Regexp = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[+/=])[A-Za-z0-9+/=\r\n]+$/;
|
|
78
68
|
|
|
79
|
-
|
|
80
|
-
const minFileSize = 100;
|
|
81
|
-
if (file.size < minFileSize) {
|
|
82
|
-
throw new Error(`INVALID_FILE_TYPE: Файл слишком маленький для SSH ключа. Минимальный размер: ${minFileSize} байт`);
|
|
83
|
-
}
|
|
69
|
+
return !base64Regexp.test(base64content);
|
|
84
70
|
};
|
|
71
|
+
|
|
72
|
+
export const validateSshKeyErrors = (value: string) => ({
|
|
73
|
+
binaryChars: checkIsBinaryCharsInContent(value),
|
|
74
|
+
emptyFile: checkIsEmptyContent(value),
|
|
75
|
+
invalidSSHKey: checkIsSshKeyError(value),
|
|
76
|
+
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFileErrorType = void 0;
|
|
4
|
-
const getFileErrorType = (error) => {
|
|
5
|
-
if (error instanceof Error) {
|
|
6
|
-
const [errorType] = error.message.split(': ');
|
|
7
|
-
switch (errorType) {
|
|
8
|
-
case 'INVALID_EXTENSION':
|
|
9
|
-
case 'INVALID_MIME_TYPE':
|
|
10
|
-
return 'INVALID_EXTENSION';
|
|
11
|
-
case 'FILE_TOO_LARGE':
|
|
12
|
-
return 'FILE_TOO_LARGE';
|
|
13
|
-
case 'INVALID_FILE_TYPE':
|
|
14
|
-
return 'INVALID_EXTENSION';
|
|
15
|
-
case 'READ_ERROR':
|
|
16
|
-
return 'READ_ERROR';
|
|
17
|
-
case 'INVALID_SSH_KEY':
|
|
18
|
-
// Проверяем специфичные типы ошибок SSH ключа
|
|
19
|
-
if (error.message.includes('пустой') || error.message.includes('empty')) {
|
|
20
|
-
return 'EMPTY_FILE';
|
|
21
|
-
}
|
|
22
|
-
if (error.message.includes('бинарные') || error.message.includes('binary')) {
|
|
23
|
-
return 'BINARY_DATA';
|
|
24
|
-
}
|
|
25
|
-
return 'INVALID_SSH_KEY';
|
|
26
|
-
default:
|
|
27
|
-
return 'UNKNOWN_ERROR';
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return 'UNKNOWN_ERROR';
|
|
31
|
-
};
|
|
32
|
-
exports.getFileErrorType = getFileErrorType;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export const getFileErrorType = (error) => {
|
|
2
|
-
if (error instanceof Error) {
|
|
3
|
-
const [errorType] = error.message.split(': ');
|
|
4
|
-
switch (errorType) {
|
|
5
|
-
case 'INVALID_EXTENSION':
|
|
6
|
-
case 'INVALID_MIME_TYPE':
|
|
7
|
-
return 'INVALID_EXTENSION';
|
|
8
|
-
case 'FILE_TOO_LARGE':
|
|
9
|
-
return 'FILE_TOO_LARGE';
|
|
10
|
-
case 'INVALID_FILE_TYPE':
|
|
11
|
-
return 'INVALID_EXTENSION';
|
|
12
|
-
case 'READ_ERROR':
|
|
13
|
-
return 'READ_ERROR';
|
|
14
|
-
case 'INVALID_SSH_KEY':
|
|
15
|
-
// Проверяем специфичные типы ошибок SSH ключа
|
|
16
|
-
if (error.message.includes('пустой') || error.message.includes('empty')) {
|
|
17
|
-
return 'EMPTY_FILE';
|
|
18
|
-
}
|
|
19
|
-
if (error.message.includes('бинарные') || error.message.includes('binary')) {
|
|
20
|
-
return 'BINARY_DATA';
|
|
21
|
-
}
|
|
22
|
-
return 'INVALID_SSH_KEY';
|
|
23
|
-
default:
|
|
24
|
-
return 'UNKNOWN_ERROR';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return 'UNKNOWN_ERROR';
|
|
28
|
-
};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export type FileErrorType =
|
|
2
|
-
| 'INVALID_EXTENSION'
|
|
3
|
-
| 'INVALID_MIME_TYPE'
|
|
4
|
-
| 'FILE_TOO_LARGE'
|
|
5
|
-
| 'INVALID_FILE_TYPE'
|
|
6
|
-
| 'READ_ERROR'
|
|
7
|
-
| 'INVALID_SSH_KEY'
|
|
8
|
-
| 'EMPTY_FILE'
|
|
9
|
-
| 'BINARY_DATA'
|
|
10
|
-
| 'UNKNOWN_ERROR';
|
|
11
|
-
|
|
12
|
-
export const getFileErrorType = (error: unknown): FileErrorType => {
|
|
13
|
-
if (error instanceof Error) {
|
|
14
|
-
const [errorType] = error.message.split(': ');
|
|
15
|
-
|
|
16
|
-
switch (errorType as FileErrorType) {
|
|
17
|
-
case 'INVALID_EXTENSION':
|
|
18
|
-
case 'INVALID_MIME_TYPE':
|
|
19
|
-
return 'INVALID_EXTENSION';
|
|
20
|
-
case 'FILE_TOO_LARGE':
|
|
21
|
-
return 'FILE_TOO_LARGE';
|
|
22
|
-
case 'INVALID_FILE_TYPE':
|
|
23
|
-
return 'INVALID_EXTENSION';
|
|
24
|
-
case 'READ_ERROR':
|
|
25
|
-
return 'READ_ERROR';
|
|
26
|
-
case 'INVALID_SSH_KEY':
|
|
27
|
-
// Проверяем специфичные типы ошибок SSH ключа
|
|
28
|
-
if (error.message.includes('пустой') || error.message.includes('empty')) {
|
|
29
|
-
return 'EMPTY_FILE';
|
|
30
|
-
}
|
|
31
|
-
if (error.message.includes('бинарные') || error.message.includes('binary')) {
|
|
32
|
-
return 'BINARY_DATA';
|
|
33
|
-
}
|
|
34
|
-
return 'INVALID_SSH_KEY';
|
|
35
|
-
default:
|
|
36
|
-
return 'UNKNOWN_ERROR';
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return 'UNKNOWN_ERROR';
|
|
41
|
-
};
|