Skip to content

Commit 642416f

Browse files
committed
Implemented supporting templates for run env
1 parent d8388c3 commit 642416f

17 files changed

Lines changed: 635 additions & 285 deletions

File tree

frontend/src/components/form/Input/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const FormInput = <T extends FieldValues>({
1010
name,
1111
control,
1212
rules,
13+
defaultValue,
1314
label,
1415
info,
1516
constraintText,
@@ -30,6 +31,7 @@ export const FormInput = <T extends FieldValues>({
3031
name={name}
3132
control={control}
3233
rules={rules}
34+
defaultValue={defaultValue}
3335
render={({ field: { onChange, ...fieldRest }, fieldState: { error } }) => {
3436
return (
3537
<FormField

frontend/src/components/form/Input/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { InputProps } from '@cloudscape-design/components/input';
55

66
export type FormInputProps<T extends FieldValues> = Omit<InputProps, 'value' | 'name'> &
77
Omit<FormFieldProps, 'errorText'> &
8-
Pick<ControllerProps<T>, 'control' | 'name' | 'rules'> & {
8+
Pick<ControllerProps<T>, 'control' | 'name' | 'rules' | 'defaultValue'> & {
99
leftContent?: ReactNode;
1010
hotspotId?: string;
1111
};

frontend/src/components/form/Select/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { FormSelectProps } from './types';
99
export const FormSelect = <T extends FieldValues>({
1010
name,
1111
rules,
12+
defaultValue,
1213
control,
1314
label,
1415
info,
@@ -24,6 +25,7 @@ export const FormSelect = <T extends FieldValues>({
2425
name={name}
2526
control={control}
2627
rules={rules}
28+
defaultValue={defaultValue}
2729
render={({ field: { onChange, ...fieldRest }, fieldState: { error } }) => {
2830
const selectedOption = props.options?.find((i) => i.value === fieldRest.value) ?? null;
2931

frontend/src/components/form/Select/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ export type FormSelectOptions = ReadonlyArray<FormSelectOption>;
77

88
export type FormSelectProps<T extends FieldValues> = Omit<SelectProps, 'value' | 'name' | 'selectedOption' | 'options'> &
99
Omit<FormFieldProps, 'errorText'> &
10-
Pick<ControllerProps<T>, 'control' | 'name' | 'rules'> & {
10+
Pick<ControllerProps<T>, 'control' | 'name' | 'rules' | 'defaultValue'> & {
1111
options: ReadonlyArray<SelectProps.Option>;
1212
};

frontend/src/components/form/Toogle/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const FormToggle = <T extends FieldValues>({
1111
name,
1212
control,
1313
rules,
14+
defaultValue,
1415
label,
1516
info,
1617
constraintText,
@@ -29,6 +30,7 @@ export const FormToggle = <T extends FieldValues>({
2930
name={name}
3031
control={control}
3132
rules={rules}
33+
defaultValue={defaultValue}
3234
render={({ field: { onChange, value, ...fieldRest }, fieldState: { error } }) => {
3335
return (
3436
<FormField

frontend/src/components/form/Toogle/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ToggleProps } from '@cloudscape-design/components/toggle';
55

66
export type FormToggleProps<T extends FieldValues> = Omit<ToggleProps, 'value' | 'checked' | 'name'> &
77
Omit<FormFieldProps, 'errorText'> &
8-
Pick<ControllerProps<T>, 'control' | 'name' | 'rules'> & {
8+
Pick<ControllerProps<T>, 'control' | 'name' | 'rules' | 'defaultValue'> & {
99
toggleDescription?: ReactNode;
1010
leftContent?: ReactNode;
1111
toggleLabel?: ReactNode | string;

frontend/src/libs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export {
55
getServerError,
66
} from './serverErrors';
77
import { format, formatDistanceToNowStrict } from 'date-fns';
8+
export { generateSecurePassword, generatePassword, generateSimplePassword } from './password';
89

910
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1011
export function arrayToRecordByKeyName<T extends { [K in keyof T]: any }, K extends keyof T>(array: T[], selector: K) {

frontend/src/libs/password.ts

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
const UPPERCASE_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
2+
const LOWERCASE_LETTERS = 'abcdefghijklmnopqrstuvwxyz';
3+
const NUMBERS = '0123456789';
4+
const SPECIAL_CHARACTERS = '@#$^_+-';
5+
6+
interface PasswordOptions {
7+
length: number;
8+
includeUppercase?: boolean;
9+
includeLowercase?: boolean;
10+
includeNumbers?: boolean;
11+
includeSpecial?: boolean;
12+
}
13+
function generatePassword(options: PasswordOptions): string {
14+
const { length, includeUppercase = true, includeLowercase = true, includeNumbers = true, includeSpecial = true } = options;
15+
16+
let allowedChars = '';
17+
18+
if (includeUppercase) allowedChars += UPPERCASE_LETTERS;
19+
if (includeLowercase) allowedChars += LOWERCASE_LETTERS;
20+
if (includeNumbers) allowedChars += NUMBERS;
21+
if (includeSpecial) allowedChars += SPECIAL_CHARACTERS;
22+
23+
if (allowedChars.length === 0) {
24+
throw new Error('No character type is selected for the password');
25+
}
26+
27+
if (length < 4) {
28+
throw new Error('The password must be at least 4 characters long');
29+
}
30+
31+
let password = '';
32+
const randomValues = new Uint32Array(length);
33+
34+
crypto.getRandomValues(randomValues);
35+
36+
for (let i = 0; i < length; i++) {
37+
const randomIndex = randomValues[i] % allowedChars.length;
38+
password += allowedChars[randomIndex];
39+
}
40+
41+
return password;
42+
}
43+
44+
function generateSimplePassword(length: number): string {
45+
const ALL_CHARS = UPPERCASE_LETTERS + LOWERCASE_LETTERS + NUMBERS + SPECIAL_CHARACTERS;
46+
47+
if (length < 1) {
48+
throw new Error('The password length must be a positive number');
49+
}
50+
51+
let password = '';
52+
const randomValues = new Uint32Array(length);
53+
54+
crypto.getRandomValues(randomValues);
55+
56+
for (let i = 0; i < length; i++) {
57+
const randomIndex = randomValues[i] % ALL_CHARS.length;
58+
password += ALL_CHARS[randomIndex];
59+
}
60+
61+
return password;
62+
}
63+
64+
function generateSecurePassword(length: number): string {
65+
if (length < 4) {
66+
throw new Error('The minimum length for a secure password is 4 characters');
67+
}
68+
69+
const charSets = [UPPERCASE_LETTERS, LOWERCASE_LETTERS, NUMBERS, SPECIAL_CHARACTERS];
70+
71+
let password = '';
72+
password += UPPERCASE_LETTERS[Math.floor(Math.random() * UPPERCASE_LETTERS.length)];
73+
password += LOWERCASE_LETTERS[Math.floor(Math.random() * LOWERCASE_LETTERS.length)];
74+
password += NUMBERS[Math.floor(Math.random() * NUMBERS.length)];
75+
password += SPECIAL_CHARACTERS[Math.floor(Math.random() * SPECIAL_CHARACTERS.length)];
76+
77+
const ALL_CHARS = charSets.join('');
78+
const remainingLength = length - 4;
79+
80+
if (remainingLength > 0) {
81+
const randomValues = new Uint32Array(remainingLength);
82+
crypto.getRandomValues(randomValues);
83+
84+
for (let i = 0; i < remainingLength; i++) {
85+
const randomIndex = randomValues[i] % ALL_CHARS.length;
86+
password += ALL_CHARS[randomIndex];
87+
}
88+
}
89+
90+
return password
91+
.split('')
92+
.sort(() => Math.random() - 0.5)
93+
.join('');
94+
}
95+
96+
export {
97+
generatePassword,
98+
generateSimplePassword,
99+
generateSecurePassword,
100+
UPPERCASE_LETTERS,
101+
LOWERCASE_LETTERS,
102+
NUMBERS,
103+
SPECIAL_CHARACTERS,
104+
};
105+
106+
export type { PasswordOptions };

0 commit comments

Comments
 (0)