Skip to content

Commit

Permalink
Merge pull request #20 from Xitija/main
Browse files Browse the repository at this point in the history
PS- 1589 Validate meeting links as per provider
  • Loading branch information
vaivk369 authored Aug 6, 2024
2 parents 462d4e0 + 9aafede commit f487240
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
41 changes: 41 additions & 0 deletions src/common/utils/validation.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
ValidatorConstraint,
ValidatorConstraintInterface,
ValidationArguments,
} from 'class-validator';

function validateMeetingUrl(url, provider) {
const providerPatterns = {
zoom: /^https:\/\/[\w-]*\.?zoom.us\/(j|my)\/[\d\w?=-]+$/,
googlemeet: /^(https:\/\/)?meet\.google\.com\/[a-zA-Z0-9-]+$/,
// microsoftteams: /^(https:\/\/)?teams\.microsoft\.com\/[a-zA-Z0-9?&=]+$/,
// Add other supported providers as needed
};
if (
!url ||
typeof url !== 'string' ||
!provider ||
typeof provider !== 'string'
) {
return false;
}

const pattern = providerPatterns[provider.toLowerCase()];
if (!pattern) {
return false; // Unsupported provider
}

return pattern.test(url);
}

@ValidatorConstraint({ name: 'urlWithProviderValidator', async: false })
export class UrlWithProviderValidator implements ValidatorConstraintInterface {
validate(url: string, args: ValidationArguments) {
const { onlineProvider } = args.object as any;
return validateMeetingUrl(url, onlineProvider);
}

defaultMessage(args: ValidationArguments) {
return 'Invalid meeting URL for the specified provider!';
}
}
15 changes: 11 additions & 4 deletions src/modules/event/dto/create-event.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
IsIn,
} from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { Transform, Type } from 'class-transformer';
import {
EndConditionType,
EventTypes,
Expand All @@ -31,8 +31,12 @@ import {
} from 'src/common/utils/types';
import { ERROR_MESSAGES } from 'src/common/utils/constants.util';
import { EndsWithZConstraint } from 'src/common/pipes/event-validation.pipe';
import { UrlWithProviderValidator } from 'src/common/utils/validation.util';

export class MeetingDetailsDto {
// Pass the provider from the parent DTO
onlineProvider: string;

@ApiProperty({ description: 'Meeting ID', example: 94292617 })
@IsString()
@IsNotEmpty()
Expand All @@ -44,7 +48,7 @@ export class MeetingDetailsDto {
})
@IsString()
@IsNotEmpty()
// @Validate(UrlValidator)
@Validate(UrlWithProviderValidator)
url: string;

@ApiProperty({ description: 'Meeting password', example: 'xxxxxx' })
Expand Down Expand Up @@ -253,7 +257,7 @@ export class CreateEventDto {
@ValidateIf((o) => o.eventType === EventTypes.online)
@IsString()
@IsNotEmpty()
@IsIn(['Zoom', 'GoogleMeet', 'MicrosoftTeams']) // Supported providers
@IsIn(['Zoom', 'GoogleMeet']) //, 'MicrosoftTeams' // Supported providers
onlineProvider: string;

@ApiProperty({
Expand All @@ -279,8 +283,11 @@ export class CreateEventDto {
@ValidateIf((o) => o.eventType === 'online')
@ValidateNested({ each: true })
@Type(() => MeetingDetailsDto)
@Transform(({ value, obj }) => {
value.onlineProvider = obj.onlineProvider; // Pass the provider to the nested DTO
return value;
})
meetingDetails: MeetingDetails;
// TODO: meet url validation

@ApiProperty({
type: Number,
Expand Down
2 changes: 1 addition & 1 deletion src/modules/event/dto/search-event.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class FilterDto {
@ApiProperty({ example: 'CohortId', description: 'CohortId' })
@IsOptional()
@IsUUID('4')
cohortId?: string
cohortId?: string;
}

export class SearchFilterDto {
Expand Down
11 changes: 5 additions & 6 deletions src/modules/event/event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ export class EventService {
// Append LIMIT and OFFSET to the query
finalquery += ` LIMIT ${limit} OFFSET ${offset}`;
const result = await this.eventRepetitionRepository.query(finalquery);
const totalCount = result[0]?.total_count

const totalCount = result[0]?.total_count;

// Add isEnded key based on endDateTime
const finalResult = result.map((event) => {
Expand All @@ -137,7 +136,7 @@ export class EventService {
};
});
if (finalResult.length === 0) {
throw new NotFoundException('Event Not Found')
throw new NotFoundException('Event Not Found');
}
return response
.status(HttpStatus.OK)
Expand All @@ -149,7 +148,7 @@ export class EventService {
),
);
} catch (error) {
throw error
throw error;
}
}

Expand Down Expand Up @@ -220,7 +219,7 @@ export class EventService {

// Handle cohortId filter
if (filters.cohortId) {
whereClauses.push(`ed."metadata"->>'cohortId'='${filters.cohortId}'`)
whereClauses.push(`ed."metadata"->>'cohortId'='${filters.cohortId}'`);
}

// Construct final query
Expand Down Expand Up @@ -539,7 +538,7 @@ export class EventService {
if (
config.endCondition.type === 'endDate' &&
occurrences[occurrences.length - 1]?.endDateTime >
new Date(config.endCondition.value)
new Date(config.endCondition.value)
) {
occurrences.pop();
}
Expand Down

0 comments on commit f487240

Please sign in to comment.