Skip to content

Commit 638271c

Browse files
feat: add campaignRequest validation
1 parent 0caa19e commit 638271c

File tree

2 files changed

+82
-12
lines changed

2 files changed

+82
-12
lines changed

src/utils/validators.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isAddress } from 'ethers';
22
import { IExec } from 'iexec';
3-
import { ValidationError, boolean, number, string } from 'yup';
3+
import { NULL_ADDRESS } from 'iexec/utils';
4+
import { ValidationError, boolean, number, object, string } from 'yup';
45

56
export const isValidProvider = async (iexec: IExec) => {
67
const client = await iexec.config.resolveContractsClient();
@@ -61,3 +62,59 @@ export const positiveNumberSchema = () =>
6162

6263
export const booleanSchema = () =>
6364
boolean().strict().typeError('${path} should be a boolean');
65+
66+
const isPositiveIntegerStringTest = (value: string) => /^\d+$/.test(value);
67+
68+
const stringSchema = () =>
69+
string().strict().typeError('${path} should be a string');
70+
71+
const positiveIntegerStringSchema = () =>
72+
string().test(
73+
'is-positive-int',
74+
'${path} should be a positive integer',
75+
(value) => isUndefined(value) || isPositiveIntegerStringTest(value)
76+
);
77+
78+
const positiveStrictIntegerStringSchema = () =>
79+
string().test(
80+
'is-positive-strict-int',
81+
'${path} should be a strictly positive integer',
82+
(value) =>
83+
isUndefined(value) ||
84+
(value !== '0' && isPositiveIntegerStringTest(value))
85+
);
86+
87+
export const campaignRequestSchema = () =>
88+
object({
89+
app: addressSchema().required(),
90+
appmaxprice: positiveIntegerStringSchema().required(),
91+
workerpool: addressSchema().required(),
92+
workerpoolmaxprice: positiveIntegerStringSchema().required(),
93+
dataset: addressSchema().oneOf([NULL_ADDRESS]).required(),
94+
datasetmaxprice: positiveIntegerStringSchema().oneOf(['0']).required(),
95+
params: stringSchema()
96+
.test(
97+
'is-valid-bulk-params',
98+
'${path} should be a valid JSON string with bulk_cid field',
99+
(value) => {
100+
try {
101+
// eslint-disable-next-line @typescript-eslint/naming-convention
102+
const { bulk_cid } = JSON.parse(value);
103+
if (typeof bulk_cid === 'string') {
104+
return true;
105+
}
106+
} catch {}
107+
return false;
108+
}
109+
)
110+
.required(),
111+
requester: addressSchema().required(),
112+
beneficiary: addressSchema().required(),
113+
callback: addressSchema().required(),
114+
category: positiveIntegerStringSchema().required(),
115+
volume: positiveStrictIntegerStringSchema().required(),
116+
tag: stringSchema().required(),
117+
trust: positiveIntegerStringSchema().required(),
118+
salt: stringSchema().required(),
119+
sign: stringSchema().required(),
120+
}).typeError('${path} should be a BulkRequest object');

src/web3mail/sendEmailCampaign.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
import { NULL_ADDRESS } from 'iexec/utils';
22
import { ValidationError } from 'yup';
33
import { handleIfProtocolError, WorkflowError } from '../utils/errors.js';
4-
import { addressOrEnsSchema, throwIfMissing } from '../utils/validators.js';
5-
import { SendEmailCampaignParams, SendEmailCampaignResponse } from './types.js';
4+
import {
5+
addressOrEnsSchema,
6+
campaignRequestSchema,
7+
throwIfMissing,
8+
} from '../utils/validators.js';
9+
import {
10+
CampaignRequest,
11+
SendEmailCampaignParams,
12+
SendEmailCampaignResponse,
13+
} from './types.js';
614
import { DataProtectorConsumer } from './internalTypes.js';
715

816
export type SendEmailCampaign = typeof sendEmailCampaign;
@@ -13,14 +21,20 @@ export const sendEmailCampaign = async ({
1321
campaignRequest,
1422
}: DataProtectorConsumer &
1523
SendEmailCampaignParams): Promise<SendEmailCampaignResponse> => {
24+
const vCampaignRequest = campaignRequestSchema()
25+
.required()
26+
.label('campaignRequest')
27+
.validateSync(campaignRequest) as CampaignRequest;
28+
1629
const vWorkerpoolAddressOrEns = addressOrEnsSchema()
1730
.required()
1831
.label('workerpoolAddressOrEns')
1932
.validateSync(workerpoolAddressOrEns);
33+
2034
if (
21-
campaignRequest?.workerpool !== NULL_ADDRESS &&
22-
vWorkerpoolAddressOrEns.toLowerCase() !==
23-
campaignRequest.workerpool.toLowerCase()
35+
vCampaignRequest.workerpool !== NULL_ADDRESS &&
36+
vCampaignRequest.workerpool.toLowerCase() !==
37+
vWorkerpoolAddressOrEns.toLowerCase()
2438
) {
2539
throw new ValidationError(
2640
"workerpoolAddressOrEns doesn't match campaignRequest workerpool"
@@ -29,12 +43,11 @@ export const sendEmailCampaign = async ({
2943

3044
try {
3145
// Process the prepared bulk request
32-
const processBulkRequestResponse: SendEmailCampaignResponse =
33-
await dataProtector.processBulkRequest({
34-
bulkRequest: campaignRequest,
35-
workerpool: vWorkerpoolAddressOrEns,
36-
waitForResult: false,
37-
});
46+
const processBulkRequestResponse = await dataProtector.processBulkRequest({
47+
bulkRequest: vCampaignRequest,
48+
workerpool: vWorkerpoolAddressOrEns,
49+
waitForResult: false,
50+
});
3851

3952
return processBulkRequestResponse;
4053
} catch (error) {

0 commit comments

Comments
 (0)