diff --git a/dictation_client/src/features/workflow/worktype/worktypeSlice.ts b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts index 224e7e3..3a358ca 100644 --- a/dictation_client/src/features/workflow/worktype/worktypeSlice.ts +++ b/dictation_client/src/features/workflow/worktype/worktypeSlice.ts @@ -45,7 +45,7 @@ export const worktypeSlice = createSlice({ action: PayloadAction<{ worktypeId: string }> ) => { const { worktypeId } = action.payload; - state.apps.worktypeId = worktypeId; + state.apps.worktypeId = worktypeId.toUpperCase(); }, changeDescription: ( state, @@ -65,7 +65,12 @@ export const worktypeSlice = createSlice({ optionItem.defaultValueType !== OPTION_ITEMS_DEFAULT_VALUE_TYPE.DEFAULT ) { optionItem.initialValue = ""; + } else { + // defaultValueTypeがDefaultの場合はinitialValueを大文字にする + optionItem.initialValue = optionItem.initialValue.toUpperCase(); } + // itemLabelを大文字にする + optionItem.itemLabel = optionItem.itemLabel.toUpperCase(); // idが一致するoptionItemを削除して、新しいoptionItemを追加する。一致するidがない場合は何もしない const optionItems = state.apps.optionItems?.filter( diff --git a/dictation_server/src/common/validators/authorId.validator.ts b/dictation_server/src/common/validators/authorId.validator.ts new file mode 100644 index 0000000..02ad278 --- /dev/null +++ b/dictation_server/src/common/validators/authorId.validator.ts @@ -0,0 +1,36 @@ +import { + ValidatorConstraint, + ValidatorConstraintInterface, + ValidationArguments, + ValidationOptions, + registerDecorator, +} from 'class-validator'; + +// 大文字英数字とアンダースコアのみを許可するバリデータ +@ValidatorConstraint({ name: 'IsAuthorId', async: false }) +export class IsAuthorId implements ValidatorConstraintInterface { + validate(value: any, args: ValidationArguments) { + return /^[A-Z0-9_]*$/.test(value); + } + defaultMessage(args: ValidationArguments) { + return `${args.property} should be uppercase alphanumeric and underscore only`; + } +} + +/** + * 大文字英数字のみを許可するバリデータ + * @param [validationOptions] + * @returns + */ +export function IsAuthorIdValid(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + name: 'IsAuthorId', + target: object.constructor, + propertyName: propertyName, + constraints: [], + options: validationOptions, + validator: IsAuthorId, + }); + }; +} diff --git a/dictation_server/src/common/validators/worktype.validator.ts b/dictation_server/src/common/validators/worktype.validator.ts index 761e9fa..6a97a50 100644 --- a/dictation_server/src/common/validators/worktype.validator.ts +++ b/dictation_server/src/common/validators/worktype.validator.ts @@ -19,7 +19,7 @@ export class IsRecorderAllowedCharacters } // 正規表現でWorktypeIDのチェックを行う - // 以下の禁則文字を除く半角英数記号 + // 以下の禁則文字を除く大文字英数記号 // \ (backslash) // / (forward slash) // : (colon) @@ -31,7 +31,7 @@ export class IsRecorderAllowedCharacters // | (vertical bar) // . (period) const regex = - /^(?!.*\\)(?!.*\/)(?!.*:)(?!.*\*)(?!.*\?)(?!.*")(?!.*<)(?!.*>)(?!.*\|)(?!.*\.)[ -~]+$/; + /^(?!.*\\)(?!.*\/)(?!.*:)(?!.*\*)(?!.*\?)(?!.*")(?!.*<)(?!.*>)(?!.*\|)(?!.*\.)[A-Z0-9 !#$%&'()+,\-;=@\[\]^_`{}~]*$/; return regex.test(value); } diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts index d661635..29c5899 100644 --- a/dictation_server/src/features/accounts/accounts.service.spec.ts +++ b/dictation_server/src/features/accounts/accounts.service.spec.ts @@ -134,8 +134,8 @@ describe('createAccount', () => { }, }); - let _subject: string = ""; - let _url: string | undefined = ""; + let _subject: string = ''; + let _url: string | undefined = ''; overrideSendgridService(service, { sendMail: async ( context: Context, @@ -197,7 +197,9 @@ describe('createAccount', () => { // 想定通りのメールが送られているか確認 expect(_subject).toBe('User Registration Notification [U-102]'); - expect(_url?.startsWith('http://localhost:8081/mail-confirm?verify=')).toBeTruthy(); + expect( + _url?.startsWith('http://localhost:8081/mail-confirm?verify='), + ).toBeTruthy(); }); it('アカウントを作成がAzure AD B2Cへの通信失敗によって失敗すると500エラーが発生する', async () => { @@ -5727,8 +5729,8 @@ describe('アカウント情報更新', () => { const module = await makeTestingModule(source); if (!module) fail(); const service = module.get(AccountsService); - let _subject: string = ""; - let _url: string | undefined = ""; + let _subject: string = ''; + let _url: string | undefined = ''; overrideSendgridService(service, { sendMail: async ( context: Context, diff --git a/dictation_server/src/features/licenses/licenses.service.spec.ts b/dictation_server/src/features/licenses/licenses.service.spec.ts index cdc56b2..69b6530 100644 --- a/dictation_server/src/features/licenses/licenses.service.spec.ts +++ b/dictation_server/src/features/licenses/licenses.service.spec.ts @@ -18,14 +18,21 @@ import { } from './test/utility'; import { UsersService } from '../users/users.service'; import { Context, makeContext } from '../../common/log'; -import { ADB2C_SIGN_IN_TYPE, LICENSE_ALLOCATED_STATUS, LICENSE_TYPE } from '../../constants'; +import { + ADB2C_SIGN_IN_TYPE, + LICENSE_ALLOCATED_STATUS, + LICENSE_TYPE, +} from '../../constants'; import { makeHierarchicalAccounts, makeTestSimpleAccount, makeTestUser, } from '../../common/test/utility'; import { LicensesRepositoryService } from '../../repositories/licenses/licenses.repository.service'; -import { overrideAdB2cService, overrideSendgridService } from '../../common/test/overrides'; +import { + overrideAdB2cService, + overrideSendgridService, +} from '../../common/test/overrides'; import { truncateAllTable } from '../../common/test/init'; describe('ライセンス注文', () => { @@ -672,7 +679,10 @@ describe('ライセンス割り当て', () => { const module = await makeTestingModule(source); if (!module) fail(); - const { id: dealerId } = await makeTestSimpleAccount(source, { company_name: "DEALER_COMPANY", tier: 4 }); + const { id: dealerId } = await makeTestSimpleAccount(source, { + company_name: 'DEALER_COMPANY', + tier: 4, + }); const { id: dealerAdminId } = await makeTestUser(source, { account_id: dealerId, external_id: 'userId_admin', @@ -682,7 +692,7 @@ describe('ライセンス割り当て', () => { const { id: accountId } = await makeTestSimpleAccount(source, { parent_account_id: dealerId, - tier: 5 + tier: 5, }); const { id: userId } = await makeTestUser(source, { account_id: accountId, @@ -740,7 +750,7 @@ describe('ライセンス割り当て', () => { }, ], })); - } + }, }); overrideSendgridService(service, { diff --git a/dictation_server/src/features/tasks/test/utility.ts b/dictation_server/src/features/tasks/test/utility.ts index 9931b6b..0f21df0 100644 --- a/dictation_server/src/features/tasks/test/utility.ts +++ b/dictation_server/src/features/tasks/test/utility.ts @@ -138,9 +138,8 @@ export const createTask = async ( label: `label${i}:audio_file_id${audioFileIdentifiers[0].id}`, value: `value${i}:audio_file_id${audioFileIdentifiers[0].id}`, }; - } - ); - + }); + await datasource.getRepository(AudioOptionItem).insert(audioOptionItems); const audioFile = audioFileIdentifiers.pop() as AudioFile; @@ -161,7 +160,7 @@ export const createTask = async ( return { taskId: task.id, audioFileId: audioFile.id }; }; -export const createAudioFile = async( +export const createAudioFile = async ( datasource: DataSource, account_id: number, owner_user_id: number, @@ -189,7 +188,7 @@ export const createAudioFile = async( }); const audioFile = audioFileIdentifiers.pop() as AudioFile; return { audioFileId: audioFile.id }; -} +}; /** * diff --git a/dictation_server/src/features/users/types/types.ts b/dictation_server/src/features/users/types/types.ts index 7cd4e44..6f4edf9 100644 --- a/dictation_server/src/features/users/types/types.ts +++ b/dictation_server/src/features/users/types/types.ts @@ -18,6 +18,7 @@ import { } from '../../../common/validators/encryptionPassword.validator'; import { IsRoleAuthorDataValid } from '../../../common/validators/roleAuthor.validator'; import { Type } from 'class-transformer'; +import { IsAuthorIdValid } from '../../../common/validators/authorId.validator'; export class ConfirmRequest { @ApiProperty() @@ -90,6 +91,7 @@ export class SignupRequest { @ApiProperty({ required: false }) @IsRoleAuthorDataValid() + @IsAuthorIdValid() authorId?: string; @ApiProperty() @@ -225,6 +227,7 @@ export class PostUpdateUserRequest { @ApiProperty({ required: false }) @IsRoleAuthorDataValid() + @IsAuthorIdValid() authorId?: string; @ApiProperty() diff --git a/dictation_server/src/repositories/user_groups/errors/types.ts b/dictation_server/src/repositories/user_groups/errors/types.ts index 4a215a7..a499a27 100644 --- a/dictation_server/src/repositories/user_groups/errors/types.ts +++ b/dictation_server/src/repositories/user_groups/errors/types.ts @@ -18,4 +18,4 @@ export class TypistGroupNameAlreadyExistError extends Error { super(message); this.name = 'TypistGroupNameAlreadyExistError'; } -} \ No newline at end of file +}