@@ -14,118 +14,130 @@ import { buildTableActionWithRule } from '../../table-actions-module/utils/build
1414import { buildActionEventWithRule } from '../../table-action-events-module/utils/build-action-event-with-rule.util.js' ;
1515import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js' ;
1616import { validateStringWithEnum } from '../../../../helpers/validators/validate-string-with-enum.js' ;
17+ import { isActionUrlHostAllowed } from '../../../../helpers/validators/is-action-url-host-allowed.js' ;
1718
1819@Injectable ( { scope : Scope . REQUEST } )
1920export class CreateActionRuleUseCase
20- extends AbstractUseCase < CreateActionRuleDS , FoundActionRulesWithActionsAndEventsDTO >
21- implements ICreateActionRule
21+ extends AbstractUseCase < CreateActionRuleDS , FoundActionRulesWithActionsAndEventsDTO >
22+ implements ICreateActionRule
2223{
23- constructor (
24- @Inject ( BaseType . GLOBAL_DB_CONTEXT )
25- protected _dbContext : IGlobalDatabaseContext ,
26- ) {
27- super ( ) ;
28- }
24+ constructor (
25+ @Inject ( BaseType . GLOBAL_DB_CONTEXT )
26+ protected _dbContext : IGlobalDatabaseContext ,
27+ ) {
28+ super ( ) ;
29+ }
2930
30- protected async implementation ( inputData : CreateActionRuleDS ) : Promise < FoundActionRulesWithActionsAndEventsDTO > {
31- const { connection_data, action_events_data, rule_data, table_actions_data } = inputData ;
32- const { connectionId, masterPwd, userId } = connection_data ;
33- const { table_name } = rule_data ;
31+ protected async implementation ( inputData : CreateActionRuleDS ) : Promise < FoundActionRulesWithActionsAndEventsDTO > {
32+ const { connection_data, action_events_data, rule_data, table_actions_data } = inputData ;
33+ const { connectionId, masterPwd, userId } = connection_data ;
34+ const { table_name } = rule_data ;
3435
35- await this . validateActionEmailsOrThrowException ( table_actions_data , userId ) ;
36- await this . validateTableNameOrThrowException ( table_name , connectionId , masterPwd ) ;
37- await this . validateTableActionDataOrThrowException ( table_actions_data ) ;
36+ await this . validateActionEmailsOrThrowException ( table_actions_data , userId ) ;
37+ await this . validateTableNameOrThrowException ( table_name , connectionId , masterPwd ) ;
38+ await this . validateTableActionDataOrThrowException ( table_actions_data ) ;
3839
39- const foundConnection = await this . _dbContext . connectionRepository . findOne ( { where : { id : connectionId } } ) ;
40- const newActionRule = buildEmptyActionRule ( rule_data , foundConnection ) ;
41- const savedActionRule = await this . _dbContext . actionRulesRepository . saveNewOrUpdatedActionRule ( newActionRule ) ;
40+ const foundConnection = await this . _dbContext . connectionRepository . findOne ( { where : { id : connectionId } } ) ;
41+ const newActionRule = buildEmptyActionRule ( rule_data , foundConnection ) ;
42+ const savedActionRule = await this . _dbContext . actionRulesRepository . saveNewOrUpdatedActionRule ( newActionRule ) ;
4243
43- const savedTableActions = await Promise . all (
44- table_actions_data . map ( ( tableAction ) => {
45- const newTableAction = buildTableActionWithRule ( tableAction , savedActionRule ) ;
46- return this . _dbContext . tableActionRepository . saveNewOrUpdatedTableAction ( newTableAction ) ;
47- } ) ,
48- ) ;
44+ const savedTableActions = await Promise . all (
45+ table_actions_data . map ( ( tableAction ) => {
46+ const newTableAction = buildTableActionWithRule ( tableAction , savedActionRule ) ;
47+ return this . _dbContext . tableActionRepository . saveNewOrUpdatedTableAction ( newTableAction ) ;
48+ } ) ,
49+ ) ;
4950
50- const savedActionEvents = await Promise . all (
51- action_events_data . map ( ( actionEvent ) => {
52- const newActionEvent = buildActionEventWithRule ( actionEvent , savedActionRule ) ;
53- return this . _dbContext . actionEventsRepository . saveNewOrUpdatedActionEvent ( newActionEvent ) ;
54- } ) ,
55- ) ;
56- savedActionRule . action_events = savedActionEvents ;
57- savedActionRule . table_actions = savedTableActions ;
58- return buildFoundActionRulesWithActionsAndEventsDTO ( savedActionRule ) ;
59- }
51+ const savedActionEvents = await Promise . all (
52+ action_events_data . map ( ( actionEvent ) => {
53+ const newActionEvent = buildActionEventWithRule ( actionEvent , savedActionRule ) ;
54+ return this . _dbContext . actionEventsRepository . saveNewOrUpdatedActionEvent ( newActionEvent ) ;
55+ } ) ,
56+ ) ;
57+ savedActionRule . action_events = savedActionEvents ;
58+ savedActionRule . table_actions = savedTableActions ;
59+ return buildFoundActionRulesWithActionsAndEventsDTO ( savedActionRule ) ;
60+ }
6061
61- private async validateActionEmailsOrThrowException (
62- table_actions_data : Array < CreateTableActionData > ,
63- userId : string ,
64- ) : Promise < void > {
65- const companyWithUsers = await this . _dbContext . companyInfoRepository . findUserCompanyWithUsers ( userId ) ;
66- const usersInCompanyEmails = companyWithUsers . users . map ( ( user ) => user . email ) ;
67- const emailsFromEmailActions : Array < string > = table_actions_data . reduce ( ( acc , table_action ) => {
68- if ( table_action . action_method === TableActionMethodEnum . EMAIL ) {
69- return acc . concat ( table_action . action_emails ) ;
70- }
71- return acc ;
72- } , [ ] ) ;
73- const emailsNotInCompany = emailsFromEmailActions . filter ( ( email ) => ! usersInCompanyEmails . includes ( email ) ) ;
74- if ( emailsNotInCompany . length > 0 ) {
75- throw new BadRequestException ( Messages . EMAILS_NOT_IN_COMPANY ( emailsNotInCompany ) ) ;
76- }
77- const emailsNotVerified = emailsFromEmailActions . filter ( ( email ) => {
78- const foundUser = companyWithUsers . users . find ( ( user ) => user . email === email ) ;
79- if ( foundUser . id === userId ) {
80- return false ;
81- }
82- return ! foundUser . isActive ;
83- } ) ;
84- if ( emailsNotVerified . length > 0 ) {
85- throw new BadRequestException ( Messages . USERS_NOT_VERIFIED ( emailsNotVerified ) ) ;
86- }
87- }
62+ private async validateActionEmailsOrThrowException (
63+ table_actions_data : Array < CreateTableActionData > ,
64+ userId : string ,
65+ ) : Promise < void > {
66+ const companyWithUsers = await this . _dbContext . companyInfoRepository . findUserCompanyWithUsers ( userId ) ;
67+ const usersInCompanyEmails = companyWithUsers . users . map ( ( user ) => user . email ) ;
68+ const emailsFromEmailActions : Array < string > = table_actions_data . reduce ( ( acc , table_action ) => {
69+ if ( table_action . action_method === TableActionMethodEnum . EMAIL ) {
70+ return acc . concat ( table_action . action_emails ) ;
71+ }
72+ return acc ;
73+ } , [ ] ) ;
74+ const emailsNotInCompany = emailsFromEmailActions . filter ( ( email ) => ! usersInCompanyEmails . includes ( email ) ) ;
75+ if ( emailsNotInCompany . length > 0 ) {
76+ throw new BadRequestException ( Messages . EMAILS_NOT_IN_COMPANY ( emailsNotInCompany ) ) ;
77+ }
78+ const emailsNotVerified = emailsFromEmailActions . filter ( ( email ) => {
79+ const foundUser = companyWithUsers . users . find ( ( user ) => user . email === email ) ;
80+ if ( foundUser . id === userId ) {
81+ return false ;
82+ }
83+ return ! foundUser . isActive ;
84+ } ) ;
85+ if ( emailsNotVerified . length > 0 ) {
86+ throw new BadRequestException ( Messages . USERS_NOT_VERIFIED ( emailsNotVerified ) ) ;
87+ }
88+ }
8889
89- private async validateTableNameOrThrowException (
90- tableName : string ,
91- connectionId : string ,
92- masterPwd : string ,
93- ) : Promise < void > {
94- const foundConnection = await this . _dbContext . connectionRepository . findAndDecryptConnection (
95- connectionId ,
96- masterPwd ,
97- ) ;
98- const dao = getDataAccessObject ( foundConnection ) ;
99- const tablesInConnection = await dao . getTablesFromDB ( ) ;
100- const tableNamesInConnection = tablesInConnection . map ( ( table ) => table . tableName ) ;
101- if ( ! tableNamesInConnection . includes ( tableName ) ) {
102- throw new BadRequestException ( Messages . TABLE_WITH_NAME_NOT_EXISTS ( tableName ) ) ;
103- }
104- }
90+ private async validateTableNameOrThrowException (
91+ tableName : string ,
92+ connectionId : string ,
93+ masterPwd : string ,
94+ ) : Promise < void > {
95+ const foundConnection = await this . _dbContext . connectionRepository . findAndDecryptConnection (
96+ connectionId ,
97+ masterPwd ,
98+ ) ;
99+ const dao = getDataAccessObject ( foundConnection ) ;
100+ const tablesInConnection = await dao . getTablesFromDB ( ) ;
101+ const tableNamesInConnection = tablesInConnection . map ( ( table ) => table . tableName ) ;
102+ if ( ! tableNamesInConnection . includes ( tableName ) ) {
103+ throw new BadRequestException ( Messages . TABLE_WITH_NAME_NOT_EXISTS ( tableName ) ) ;
104+ }
105+ }
105106
106- private async validateTableActionDataOrThrowException ( tableActions : Array < CreateTableActionData > ) : Promise < void > {
107- for ( const action of tableActions ) {
108- if ( action . action_method === TableActionMethodEnum . EMAIL ) {
109- if ( ! action . action_emails || action . action_emails . length === 0 ) {
110- throw new BadRequestException ( Messages . EMAILS_REQUIRED_FOR_EMAIL_ACTION ) ;
111- }
112- }
113- if ( action . action_method === TableActionMethodEnum . SLACK ) {
114- if ( ! action . action_slack_url ) {
115- throw new BadRequestException ( Messages . SLACK_URL_MISSING ) ;
116- }
117- }
118- if ( ! validateStringWithEnum ( action . action_method , TableActionMethodEnum ) ) {
119- throw new BadRequestException ( Messages . INVALID_ACTION_METHOD ( action . action_method ) ) ;
120- }
121- if ( action . action_method === TableActionMethodEnum . URL ) {
122- if ( process . env . NODE_ENV === 'test' ) {
123- return ;
124- }
125- if ( ! action . action_url || ! ValidationHelper . isValidUrl ( action . action_url ) ) {
126- throw new BadRequestException ( Messages . URL_INVALID ) ;
127- }
128- }
129- }
130- }
107+ private async validateTableActionDataOrThrowException ( tableActions : Array < CreateTableActionData > ) : Promise < void > {
108+ for ( const action of tableActions ) {
109+ if ( action . action_method === TableActionMethodEnum . EMAIL ) {
110+ if ( ! action . action_emails || action . action_emails . length === 0 ) {
111+ throw new BadRequestException ( Messages . EMAILS_REQUIRED_FOR_EMAIL_ACTION ) ;
112+ }
113+ }
114+ if ( action . action_method === TableActionMethodEnum . SLACK ) {
115+ if ( ! action . action_slack_url ) {
116+ throw new BadRequestException ( Messages . SLACK_URL_MISSING ) ;
117+ }
118+ if ( process . env . NODE_ENV !== 'test' && ! ValidationHelper . isValidUrl ( action . action_slack_url ) ) {
119+ throw new BadRequestException ( Messages . URL_INVALID ) ;
120+ }
121+ const isSlackUrlAllowed = await isActionUrlHostAllowed ( action . action_slack_url ) ;
122+ if ( ! isSlackUrlAllowed ) {
123+ throw new BadRequestException ( Messages . ACTION_URL_HOST_NOT_ALLOWED ) ;
124+ }
125+ }
126+ if ( ! validateStringWithEnum ( action . action_method , TableActionMethodEnum ) ) {
127+ throw new BadRequestException ( Messages . INVALID_ACTION_METHOD ( action . action_method ) ) ;
128+ }
129+ if ( action . action_method === TableActionMethodEnum . URL ) {
130+ if (
131+ process . env . NODE_ENV !== 'test' &&
132+ ( ! action . action_url || ! ValidationHelper . isValidUrl ( action . action_url ) )
133+ ) {
134+ throw new BadRequestException ( Messages . URL_INVALID ) ;
135+ }
136+ const isUrlAllowed = await isActionUrlHostAllowed ( action . action_url ) ;
137+ if ( ! isUrlAllowed ) {
138+ throw new BadRequestException ( Messages . ACTION_URL_HOST_NOT_ALLOWED ) ;
139+ }
140+ }
141+ }
142+ }
131143}
0 commit comments