diff --git a/packages/api/src/controllers/v2/community/details.ts b/packages/api/src/controllers/v2/community/details.ts index f91c74521..ecdeecf32 100644 --- a/packages/api/src/controllers/v2/community/details.ts +++ b/packages/api/src/controllers/v2/community/details.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; +import { config, services } from '@impactmarket/core'; import { getAddress } from '@ethersproject/address'; -import { services } from '@impactmarket/core'; import { RequestWithUser } from '../../../middlewares/core'; import { standardResponse } from '../../../utils/api'; @@ -16,30 +16,18 @@ class CommunityController { getManagers = (req: RequestWithUser, res: Response) => { const community = req.params.id; const { search } = req.query; - let { state, offset, limit, orderBy } = req.query; - if (state === undefined || typeof state !== 'string') { - state = undefined; - } - if (offset === undefined || typeof offset !== 'string') { - offset = '0'; - } - if (limit === undefined || typeof limit !== 'string') { - limit = '5'; - } - if (orderBy === undefined || typeof orderBy !== 'string') { - orderBy = undefined; - } + const { state, offset, limit, orderBy } = req.query; this.detailsService .listManagers( parseInt(community, 10), - parseInt(offset, 10), - parseInt(limit, 10), + offset ? parseInt(offset as string, 10) : config.defaultOffset, + limit ? parseInt(limit as string, 10) : config.defaultLimit, { - state: state ? parseInt(state, 10) : undefined + state: state ? parseInt(state as string, 10) : undefined }, search !== undefined && typeof search === 'string' ? search : undefined, - orderBy, + orderBy as string, req.user?.address ) .then(r => standardResponse(res, 200, true, r)) @@ -57,35 +45,23 @@ class CommunityController { return; } const { suspect, inactivity, unidentified, loginInactivity, search, lastActivity_lt } = req.query; - let { state, offset, limit, orderBy } = req.query; - if (state === undefined || typeof state !== 'string') { - state = undefined; - } - if (offset === undefined || typeof offset !== 'string') { - offset = '0'; - } - if (limit === undefined || typeof limit !== 'string') { - limit = '5'; - } - if (orderBy === undefined || typeof orderBy !== 'string') { - orderBy = undefined; - } + const { state, offset, limit, orderBy } = req.query; this.detailsService .listBeneficiaries( req.user.address, parseInt(req.params.id, 10), - parseInt(offset, 10), - parseInt(limit, 10), + offset ? parseInt(offset as string, 10) : config.defaultOffset, + limit ? parseInt(limit as string, 10) : config.defaultLimit, { - state: state ? parseInt(state, 10) : undefined, + state: state ? parseInt(state as string, 10) : undefined, suspect: suspect ? suspect === 'true' : undefined, inactivity: inactivity ? inactivity === 'true' : undefined, unidentified: unidentified ? unidentified === 'true' : undefined, loginInactivity: loginInactivity ? loginInactivity === 'true' : undefined }, search !== undefined && typeof search === 'string' ? search : undefined, - orderBy, - lastActivity_lt && typeof lastActivity_lt === 'string' ? parseInt(lastActivity_lt, 10) : undefined + orderBy as string, + lastActivity_lt ? parseInt(lastActivity_lt as string, 10) : undefined ) .then(r => standardResponse(res, 200, true, r)) .catch(e => standardResponse(res, 400, false, '', { error: e })); @@ -93,12 +69,7 @@ class CommunityController { findBy = (req: RequestWithUser, res: Response) => { const { idOrAddress } = req.params; - if (idOrAddress.startsWith('0x')) { - this.detailsService - .findByContractAddress(getAddress(idOrAddress), req.user?.address, req.query) - .then(community => standardResponse(res, 200, !!community, community)) - .catch(e => standardResponse(res, 400, false, '', { error: e })); - } else { + if (typeof idOrAddress === 'number') { const communityId = parseInt(idOrAddress, 10); if (!communityId) { standardResponse(res, 400, false, '', { @@ -114,6 +85,11 @@ class CommunityController { .findById(communityId, req.user?.address, req.query) .then(community => standardResponse(res, 200, true, community)) .catch(e => standardResponse(res, 400, false, '', { error: e })); + } else { + this.detailsService + .findByContractAddress(getAddress(idOrAddress), req.user?.address, req.query) + .then(community => standardResponse(res, 200, !!community, community)) + .catch(e => standardResponse(res, 400, false, '', { error: e })); } }; diff --git a/packages/api/src/routes/v2/community/create.ts b/packages/api/src/routes/v2/community/create.ts index 8c3d4e4a5..cab2c47e8 100644 --- a/packages/api/src/routes/v2/community/create.ts +++ b/packages/api/src/routes/v2/community/create.ts @@ -2,7 +2,7 @@ import { Router } from 'express'; import { CommunityController } from '../../../controllers/v2/community/create'; import { authenticateToken, verifySignature } from '../../../middlewares'; -import CommunityValidator from '../../../validators/community'; +import { create, edit, editSubmission, review } from '../../../validators/community'; export default (route: Router): void => { const controller = new CommunityController(); @@ -96,7 +96,7 @@ export default (route: Router): void => { * security: * - BearerToken: [] */ - route.post('/', authenticateToken, CommunityValidator.create, controller.create); + route.post('/', authenticateToken, create, controller.create); /** * @swagger @@ -179,7 +179,7 @@ export default (route: Router): void => { * security: * - BearerToken: [] */ - route.patch('/:id', authenticateToken, CommunityValidator.editSubmission, controller.editSubmission); + route.patch('/:id', authenticateToken, editSubmission, controller.editSubmission); /** * @swagger @@ -213,7 +213,7 @@ export default (route: Router): void => { * security: * - BearerToken: [] */ - route.put('/:id/review', authenticateToken, CommunityValidator.review, controller.review); + route.put('/:id/review', authenticateToken, review, controller.review); /** * @swagger @@ -254,5 +254,5 @@ export default (route: Router): void => { * - SignatureMessage: [] * - Signature: [] */ - route.put('/:id', authenticateToken, verifySignature, CommunityValidator.edit, controller.edit); + route.put('/:id', authenticateToken, verifySignature, edit, controller.edit); }; diff --git a/packages/api/src/routes/v2/community/details.ts b/packages/api/src/routes/v2/community/details.ts index 2ae0d775e..e1deda77f 100644 --- a/packages/api/src/routes/v2/community/details.ts +++ b/packages/api/src/routes/v2/community/details.ts @@ -5,6 +5,11 @@ import { CommunityController } from '../../../controllers/v2/community/details'; import { authenticateToken, optionalAuthentication, verifySignature } from '../../../middlewares'; import { cache } from '../../../middlewares/cache-redis'; import { cacheIntervals } from '../../../utils/api'; +import { + getBeneficiariesValidator, + getCommunityByIDOrAddressValidator, + getCommunityValidator +} from '../../../validators/community'; const upload = multer({ storage: multer.memoryStorage(), @@ -123,7 +128,7 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/getManagersResponse' */ - route.get('/:id/managers/:query?', optionalAuthentication, controller.getManagers); + route.get('/:id/managers/:query?', optionalAuthentication, getCommunityValidator, controller.getManagers); /** * @swagger @@ -148,7 +153,7 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/UbiCommunityContract' */ - route.get('/:id/contract', controller.getContract); + route.get('/:id/contract', getCommunityValidator, controller.getContract); /** * @swagger @@ -173,7 +178,7 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/UbiCommunityContract' */ - route.get('/:id/ambassador', optionalAuthentication, controller.getAmbassador); + route.get('/:id/ambassador', getCommunityValidator, optionalAuthentication, controller.getAmbassador); /** * @swagger @@ -194,7 +199,7 @@ export default (route: Router): void => { * "200": * description: OK */ - route.get('/:id/merchant', controller.getMerchant); + route.get('/:id/merchant', getCommunityValidator, controller.getMerchant); /** * @swagger @@ -259,7 +264,8 @@ export default (route: Router): void => { route.get( '/:id/beneficiaries/:query?', authenticateToken, - cache(cacheIntervals.halfHour), + // cache(cacheIntervals.halfHour), + getBeneficiariesValidator, controller.getBeneficiaries ); @@ -293,7 +299,7 @@ export default (route: Router): void => { * longitude: * type: integer */ - route.get('/:id/claims-location', cache(cacheIntervals.oneDay), controller.getClaimLocation); + route.get('/:id/claims-location', cache(cacheIntervals.oneDay), getCommunityValidator, controller.getClaimLocation); /** * @swagger @@ -341,7 +347,7 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/UbiPromoter' */ - route.get('/:id/promoter', controller.getPromoter); + route.get('/:id/promoter', getCommunityValidator, controller.getPromoter); /** * @swagger @@ -401,7 +407,7 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/UbiCommunityCampaign' */ - route.get('/:id/campaign', cache(cacheIntervals.oneHour), controller.getCampaign); + route.get('/:id/campaign', cache(cacheIntervals.oneHour), getCommunityValidator, controller.getCampaign); /** * @swagger @@ -433,5 +439,5 @@ export default (route: Router): void => { * schema: * $ref: '#/components/schemas/UbiCommunity' */ - route.get('/:idOrAddress/:query?', optionalAuthentication, controller.findBy); + route.get('/:idOrAddress/:query?', optionalAuthentication, getCommunityByIDOrAddressValidator, controller.findBy); }; diff --git a/packages/api/src/routes/v2/learnAndEarn.ts b/packages/api/src/routes/v2/learnAndEarn.ts index a35c05af8..f23d152fe 100644 --- a/packages/api/src/routes/v2/learnAndEarn.ts +++ b/packages/api/src/routes/v2/learnAndEarn.ts @@ -1,14 +1,20 @@ import { Router } from 'express'; +import { + answer, + createLevel, + listLessonsValidator, + listLevels, + registerClaimRewards, + startLesson +} from '../../validators/learnAndEarn'; import { authenticateToken, optionalAuthentication } from '../../middlewares'; import { cache } from '../../middlewares/cache-redis'; import { cacheIntervals } from '../../utils/api'; import LearnAndEarnController from '../../controllers/v2/learnAndEarn'; -import LearnAndEarnValidator from '../../validators/learnAndEarn'; export default (app: Router): void => { const learnAndEarnController = new LearnAndEarnController(); - const learnAndEarnValidator = new LearnAndEarnValidator(); const route = Router(); app.use('/learn-and-earn', route); @@ -68,7 +74,7 @@ export default (app: Router): void => { '/levels', optionalAuthentication, cache(cacheIntervals.halfHour, true), - learnAndEarnValidator.listLevels, + listLevels, learnAndEarnController.listLevels ); @@ -102,14 +108,9 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.post('/levels', authenticateToken, learnAndEarnValidator.createLevel, learnAndEarnController.createLevel); + route.post('/levels', authenticateToken, createLevel, learnAndEarnController.createLevel); - route.put( - '/levels', - authenticateToken, - learnAndEarnValidator.registerClaimRewards, - learnAndEarnController.registerClaimRewards - ); + route.put('/levels', authenticateToken, registerClaimRewards, learnAndEarnController.registerClaimRewards); /** * @swagger @@ -136,6 +137,7 @@ export default (app: Router): void => { '/levels/:id', optionalAuthentication, cache(cacheIntervals.halfHour, true), + listLessonsValidator, learnAndEarnController.listLessons ); @@ -165,7 +167,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.put('/lessons', authenticateToken, learnAndEarnValidator.answer, learnAndEarnController.answer); + route.put('/lessons', authenticateToken, answer, learnAndEarnController.answer); /** * @swagger @@ -189,7 +191,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.post('/lessons', authenticateToken, learnAndEarnValidator.startLesson, learnAndEarnController.startLesson); + route.post('/lessons', authenticateToken, startLesson, learnAndEarnController.startLesson); /** * trigger update diff --git a/packages/api/src/routes/v2/microcredit/list.ts b/packages/api/src/routes/v2/microcredit/list.ts index 1f25df72c..6d22769e0 100644 --- a/packages/api/src/routes/v2/microcredit/list.ts +++ b/packages/api/src/routes/v2/microcredit/list.ts @@ -5,8 +5,10 @@ import { authenticateToken, onlyAuthorizedRoles, verifySignature } from '../../. import { cache } from '../../../middlewares/cache-redis'; import { cacheIntervals } from '../../../utils/api'; import { + getFormValidator, listApplicationsValidator, listBorrowersValidator, + listManagersByCountryValidator, queryGetBorrowerValidator, repaymentsHistoryValidator } from '../../../validators/microcredit'; @@ -287,7 +289,7 @@ export default (route: Router): void => { * security: * - BearerToken: [] */ - route.get('/form/:id', authenticateToken, controller.getUserForm); + route.get('/form/:id', authenticateToken, getFormValidator, controller.getUserForm); /** * @swagger @@ -309,7 +311,12 @@ export default (route: Router): void => { * "200": * description: OK */ - route.get('/managers/:country', cache(cacheIntervals.oneHour), controller.getLoanManagersByCountry); + route.get( + '/managers/:country', + cache(cacheIntervals.oneHour), + listManagersByCountryValidator, + controller.getLoanManagersByCountry + ); /** * @swagger diff --git a/packages/api/src/routes/v2/referrals/index.ts b/packages/api/src/routes/v2/referrals/index.ts index 8960b1d3e..2bef7abb7 100644 --- a/packages/api/src/routes/v2/referrals/index.ts +++ b/packages/api/src/routes/v2/referrals/index.ts @@ -3,7 +3,7 @@ import { Router } from 'express'; import { authenticateToken, verifyTypedSignature } from '~middlewares/index'; import { cache } from '~middlewares/cache-redis'; import { cacheIntervals } from '~utils/api'; -import { referralPostValidator } from '~validators/referral'; +import { getReferralCodeValidator, referralPostValidator } from '~validators/referral'; import ReferralController from '~controllers/v2/referral'; export default (app: Router): void => { @@ -61,6 +61,7 @@ export default (app: Router): void => { authenticateToken, verifyTypedSignature, cache(cacheIntervals.fiveMinutes), + getReferralCodeValidator, controller.getByCampaign ); diff --git a/packages/api/src/routes/v2/story.ts b/packages/api/src/routes/v2/story.ts index ed53d1bc4..eb454b64a 100644 --- a/packages/api/src/routes/v2/story.ts +++ b/packages/api/src/routes/v2/story.ts @@ -1,14 +1,13 @@ import { Router } from 'express'; +import { add, addComment, getStoryCommentsValidator, getStoryValidator } from '../../validators/story'; import { authenticateToken, optionalAuthentication } from '../../middlewares'; import { cache } from '../../middlewares/cache-redis'; import { cacheIntervals } from '../../utils/api'; import StoryController from '../../controllers/v2/story'; -import StoryValidator from '../../validators/story'; export default (app: Router): void => { const storyController = new StoryController(); - const storyValidator = new StoryValidator(); const route = Router(); app.use('/stories', route); @@ -68,7 +67,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.post('/', authenticateToken, storyValidator.add, storyController.add); + route.post('/', authenticateToken, add, storyController.add); /** * @swagger @@ -136,7 +135,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.get('/:id', optionalAuthentication, storyController.getById); + route.get('/:id', optionalAuthentication, getStoryValidator, storyController.getById); /** * @swagger @@ -289,7 +288,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.get('/:id/comments/:query?', storyController.getComments); + route.get('/:id/comments/:query?', getStoryCommentsValidator, storyController.getComments); /** * @swagger @@ -321,7 +320,7 @@ export default (app: Router): void => { * security: * - BearerToken: [] */ - route.post('/:id/comments', authenticateToken, storyValidator.addComment, storyController.addComment); + route.post('/:id/comments', authenticateToken, addComment, storyController.addComment); /** * @swagger diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts index bf1dbaf3c..6fe1f20d2 100644 --- a/packages/api/src/server.ts +++ b/packages/api/src/server.ts @@ -173,7 +173,9 @@ export default (app: express.Application): void => { message: 'invalid payloads', details: error.details.get('query') ? error.details.get('query').details - : error.details.get('body').details + : error.details.get('params') + ? error.details.get('params').details + : error.details.get('body').details } }); } diff --git a/packages/api/src/validators/community.ts b/packages/api/src/validators/community.ts index b2cee1eb0..9237a9b18 100644 --- a/packages/api/src/validators/community.ts +++ b/packages/api/src/validators/community.ts @@ -2,6 +2,104 @@ import { Joi, celebrate } from 'celebrate'; import { defaultSchema } from './defaultSchema'; +const getCommunitySchema = defaultSchema.object<{ id: number; query: any }>({ + id: Joi.number().required(), + query: Joi.any() // validation on getCommunityQuerySchema +}); +const getCommunityQuerySchema = defaultSchema.object<{ + limit: number; + offset: number; + state: number; + search: string; + orderBy: string; +}>({ + limit: Joi.number().optional(), + offset: Joi.number().optional(), + state: Joi.number().optional().valid(0, 1), + search: Joi.string().optional(), + orderBy: Joi.string() + .optional() + .valid( + 'state', + 'state:asc', + 'state:desc', + 'added', + 'added:asc', + 'added:desc', + 'removed', + 'removed:asc', + 'removed:desc', + 'since', + 'since:asc', + 'since:desc', + 'until', + 'until:asc', + 'until:desc' + ) +}); + +const getBeneficiariesQuerySchema = defaultSchema.object<{ + limit: number; + offset: number; + state: number; + search: string; + orderBy: string; + lastActivity_lt: number; +}>({ + limit: Joi.number().optional(), + offset: Joi.number().optional(), + state: Joi.number().optional().valid(0, 1, 2), + search: Joi.string().optional(), + orderBy: Joi.string() + .optional() + .valid( + 'state', + 'state:asc', + 'state:desc', + 'claimed', + 'claimed:asc', + 'claimed:desc', + 'since', + 'since:asc', + 'since:desc' + ), + lastActivity_lt: Joi.number().optional() +}); + +const getCommunityByIDOrAddressQuerySchema = defaultSchema.object<{ state: string }>({ + state: Joi.string().optional().valid('ubi', 'base') +}); + +const getCommunityByIDOrAddressSchema = defaultSchema.object<{ idOrAddress: number | string; query: any }>({ + idOrAddress: Joi.alternatives( + Joi.number(), + Joi.string() + .messages({ + startWith: 'An address should start with 0x' + }) + .custom((value, helpers) => { + if (!value.startsWith('0x')) { + return helpers.error('startWith'); + } + return value; + }) + ), + query: Joi.any() // validation on getCommunityByIDOrAddressQuerySchema +}); + +const getCommunityValidator = celebrate({ + params: getCommunitySchema, + query: getCommunityQuerySchema +}); +const getBeneficiariesValidator = celebrate({ + params: getCommunitySchema, + query: getBeneficiariesQuerySchema +}); +const getCommunityByIDOrAddressValidator = celebrate({ + params: getCommunityByIDOrAddressSchema, + query: getCommunityByIDOrAddressQuerySchema +}); + const create = celebrate({ body: defaultSchema.object({ requestByAddress: Joi.string().required(), @@ -66,9 +164,12 @@ const review = celebrate({ }) }); -export default { +export { create, edit, editSubmission, - review + review, + getCommunityValidator, + getCommunityByIDOrAddressValidator, + getBeneficiariesValidator }; diff --git a/packages/api/src/validators/learnAndEarn.ts b/packages/api/src/validators/learnAndEarn.ts index bff1c7215..474eb0a6b 100644 --- a/packages/api/src/validators/learnAndEarn.ts +++ b/packages/api/src/validators/learnAndEarn.ts @@ -1,19 +1,23 @@ import { Joi, celebrate } from 'celebrate'; +import { createValidator } from '../utils/queryValidator'; import { defaultSchema } from './defaultSchema'; + import config from '~config/index'; +const validator = createValidator(); + // I wish this comes true https://github.com/hapijs/joi/issues/2864#issuecomment-1322736004 // This should match Joi validations -export type AnswerRequestType = { +type AnswerRequestType = { lesson: string; answers: number[]; }; -export type StartLessonRequestType = { +type StartLessonRequestType = { lesson: string; }; -export type ListLevelsRequestType = { +type ListLevelsRequestType = { status?: 'available' | 'started' | 'completed'; category?: string; limit?: number; @@ -21,55 +25,70 @@ export type ListLevelsRequestType = { language?: string; client?: number; }; -export type RegisterClaimRewardsRequestType = { +type RegisterClaimRewardsRequestType = { transactionHash: string; }; -class LearnAndEarnValidator { - answer = celebrate({ - body: defaultSchema.object({ - answers: defaultSchema.array().items(Joi.number().required()).required(), - lesson: Joi.string().required() - }) - }); +const listLessonsSchema = defaultSchema.object<{ id: number }>({ + id: Joi.number().required() +}); + +const listLessonsValidator = validator.params(listLessonsSchema); - startLesson = celebrate({ - body: defaultSchema.object({ - lesson: Joi.string().required() - }) - }); +const answer = celebrate({ + body: defaultSchema.object({ + answers: defaultSchema.array().items(Joi.number().required()).required(), + lesson: Joi.string().required() + }) +}); - listLevels = celebrate({ - query: { - status: Joi.string().optional().valid('available', 'started', 'completed'), // TODO: add .default('available'), - category: Joi.string().optional(), - limit: Joi.number().optional().default(config.defaultLimit), - offset: Joi.number().optional().default(config.defaultOffset), - language: Joi.string().optional(), // TODO: make required - client: Joi.number().optional().default(1) - } - }); +const startLesson = celebrate({ + body: defaultSchema.object({ + lesson: Joi.string().required() + }) +}); - registerClaimRewards = celebrate({ - body: defaultSchema.object({ - transactionHash: Joi.string().required() - }) - }); +const listLevels = celebrate({ + query: { + status: Joi.string().optional().valid('available', 'started', 'completed'), // TODO: add .default('available'), + category: Joi.string().optional(), + limit: Joi.number().optional().default(config.defaultLimit), + offset: Joi.number().optional().default(config.defaultOffset), + language: Joi.string().optional(), // TODO: make required + client: Joi.number().optional().default(1) + } +}); - createLevel = celebrate({ - body: defaultSchema.object({ - rules: defaultSchema - .object({ - countries: defaultSchema.array().items(Joi.string().length(2).required()).optional(), - roles: defaultSchema - .array() - .items(Joi.string().valid('manager', 'beneficiary', 'ambassador').required()) - .optional(), - limitUsers: Joi.number().optional() - }) - .optional() - }) - }); -} +const registerClaimRewards = celebrate({ + body: defaultSchema.object({ + transactionHash: Joi.string().required() + }) +}); -export default LearnAndEarnValidator; +const createLevel = celebrate({ + body: defaultSchema.object({ + rules: defaultSchema + .object({ + countries: defaultSchema.array().items(Joi.string().length(2).required()).optional(), + roles: defaultSchema + .array() + .items(Joi.string().valid('manager', 'beneficiary', 'ambassador').required()) + .optional(), + limitUsers: Joi.number().optional() + }) + .optional() + }) +}); + +export { + answer, + startLesson, + listLevels, + registerClaimRewards, + createLevel, + listLessonsValidator, + AnswerRequestType, + StartLessonRequestType, + ListLevelsRequestType, + RegisterClaimRewardsRequestType +}; diff --git a/packages/api/src/validators/microcredit.ts b/packages/api/src/validators/microcredit.ts index 3ac928ae0..0c170f492 100644 --- a/packages/api/src/validators/microcredit.ts +++ b/packages/api/src/validators/microcredit.ts @@ -96,6 +96,14 @@ const queryGetBorrowerSchema = defaultSchema.object<{ address: string; formId: n include: Joi.alternatives(Joi.string(), Joi.array()).optional().default([]) }); +const getFormSchema = defaultSchema.object<{ id: number }>({ + id: Joi.number().required() +}); + +const listManagersByCountrySchema = defaultSchema.object<{ country: string }>({ + country: Joi.string().length(2).required() +}); + interface ListBorrowersRequestSchema extends ValidatedRequestSchema { [ContainerTypes.Query]: ListBorrowersType; } @@ -145,6 +153,8 @@ type PutApplicationsRequestType = [ } ]; +const getFormValidator = validator.params(getFormSchema); +const listManagersByCountryValidator = validator.params(listManagersByCountrySchema); const listBorrowersValidator = validator.query(queryListBorrowersSchema); const listApplicationsValidator = validator.query(queryListApplicationsSchema); const repaymentsHistoryValidator = validator.query(queryRepaymentsHistorySchema); @@ -198,6 +208,8 @@ const addNote = celebrate({ }); export { + getFormValidator, + listManagersByCountryValidator, listBorrowersValidator, listApplicationsValidator, preSignerUrlFromAWSValidator, diff --git a/packages/api/src/validators/referral.ts b/packages/api/src/validators/referral.ts index 8a5c3d0cf..aa3d3904d 100644 --- a/packages/api/src/validators/referral.ts +++ b/packages/api/src/validators/referral.ts @@ -1,13 +1,24 @@ import { Joi, celebrate } from 'celebrate'; +import { createValidator } from '../utils/queryValidator'; import { defaultSchema } from './defaultSchema'; -export type ReferralRequestType = { +const validator = createValidator(); + +type ReferralRequestType = { code: string; }; -export const referralPostValidator = celebrate({ +const getReferralCodeSchema = defaultSchema.object<{ cid: number }>({ + cid: Joi.number().required() +}); + +const getReferralCodeValidator = validator.params(getReferralCodeSchema); + +const referralPostValidator = celebrate({ body: defaultSchema.object({ code: Joi.string().required() }) }); + +export { referralPostValidator, getReferralCodeValidator, ReferralRequestType }; diff --git a/packages/api/src/validators/story.ts b/packages/api/src/validators/story.ts index b6adee639..72df72907 100644 --- a/packages/api/src/validators/story.ts +++ b/packages/api/src/validators/story.ts @@ -1,20 +1,37 @@ import { Joi, celebrate } from 'celebrate'; +import { createValidator } from '../utils/queryValidator'; import { defaultSchema } from './defaultSchema'; -class StoryValidator { - add = celebrate({ - body: defaultSchema.object({ - message: Joi.string().optional(), - storyMedia: Joi.array().items(Joi.string()).optional() - }) - }); - - addComment = celebrate({ - body: defaultSchema.object({ - comment: Joi.string().required() - }) - }); -} - -export default StoryValidator; +const validator = createValidator(); + +const getStorySchema = defaultSchema.object<{ id: number; query: any }>({ + id: Joi.number().required(), + query: Joi.any() // validation on getStoryQuerySchema +}); + +const getStoryQuerySchema = defaultSchema.object<{ limit: number; offset: number }>({ + limit: Joi.number().optional(), + offset: Joi.number().optional() +}); + +const getStoryValidator = validator.params(getStorySchema); +const getStoryCommentsValidator = celebrate({ + params: getStorySchema, + query: getStoryQuerySchema +}); + +const add = celebrate({ + body: defaultSchema.object({ + message: Joi.string().optional(), + storyMedia: Joi.array().items(Joi.string()).optional() + }) +}); + +const addComment = celebrate({ + body: defaultSchema.object({ + comment: Joi.string().required() + }) +}); + +export { getStoryValidator, getStoryCommentsValidator, add, addComment };