This commit is contained in:
2026-06-12 16:13:39 -05:00
parent 2492720470
commit e63c0f5998
6 changed files with 23 additions and 6 deletions

View File

@@ -10,7 +10,7 @@ import { GeoService } from '../geo/geo.service';
import { BusinessListing, BusinessListingSchema } from '../models/db.model';
import { BusinessListingCriteria, JwtUser } from '../models/main.model';
import { getDistanceQuery, splitName } from '../utils';
import { generateSlug, extractShortIdFromSlug, isSlug } from '../utils/slug.utils';
import { generateSlug, extractShortIdFromSlug, isSlug, isUUID } from '../utils/slug.utils';
@Injectable()
export class BusinessListingService {
@@ -271,6 +271,9 @@ export class BusinessListingService {
}
} else {
this.logger.debug(`Detected as UUID: ${slugOrId}`);
if (!isUUID(slugOrId)) {
throw new BadRequestException(`Invalid identifier format: ${slugOrId}`);
}
}
return this.findBusinessesById(id, user);

View File

@@ -11,7 +11,7 @@ import { GeoService } from '../geo/geo.service';
import { CommercialPropertyListing, CommercialPropertyListingSchema } from '../models/db.model';
import { CommercialPropertyListingCriteria, JwtUser } from '../models/main.model';
import { getDistanceQuery, splitName } from '../utils';
import { generateSlug, extractShortIdFromSlug, isSlug } from '../utils/slug.utils';
import { generateSlug, extractShortIdFromSlug, isSlug, isUUID } from '../utils/slug.utils';
@Injectable()
export class CommercialPropertyService {
@@ -166,6 +166,9 @@ export class CommercialPropertyService {
}
} else {
this.logger.debug(`Detected as UUID: ${slugOrId}`);
if (!isUUID(slugOrId)) {
throw new BadRequestException(`Invalid identifier format: ${slugOrId}`);
}
}
return this.findCommercialPropertiesById(id, user);

View File

@@ -1,9 +1,10 @@
import { Controller, Get, Inject, Param, Request, UseGuards } from '@nestjs/common';
import { Controller, Get, Inject, Param, Request, UseGuards, BadRequestException } from '@nestjs/common';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { OptionalAuthGuard } from 'src/jwt-auth/optional-auth.guard';
import { Logger } from 'winston';
import { BusinessListingService } from './business-listing.service';
import { CommercialPropertyService } from './commercial-property.service';
import { isUUID } from '../utils/slug.utils';
@Controller('listings/undefined')
export class UnknownListingsController {
@@ -16,6 +17,9 @@ export class UnknownListingsController {
@UseGuards(OptionalAuthGuard)
@Get(':id')
async findById(@Request() req, @Param('id') id: string): Promise<any> {
if (!isUUID(id)) {
throw new BadRequestException(`Invalid identifier format: ${id}`);
}
try {
return await this.businessListingsService.findBusinessesById(id, req.user);
} catch (error) {

View File

@@ -107,6 +107,13 @@ export function isValidSlug(slug: string): boolean {
return lastPart.length === 8 && /^[a-z0-9]{8}$/.test(lastPart);
}
/**
* Check if a string is a valid UUID v4
*/
export function isUUID(param: string): boolean {
return /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(param);
}
/**
* Check if a parameter is a slug (vs a UUID)
*

View File

@@ -23,7 +23,7 @@
'Business' }}</td>
<td class="py-2 px-4">{{ listing.location.name ? listing.location.name : listing.location.county }}, {{
listing.location.state }}</td>
<td class="py-2 px-4">${{ $any(listing).price.toLocaleString() }}</td>
<td class="py-2 px-4">${{ $any(listing).price ? $any(listing).price.toLocaleString() : 'Price on Request' }}</td>
<td class="py-2 px-4 flex">
@if($any(listing).listingsCategory==='business'){
<button class="bg-green-500 text-white w-10 h-10 flex items-center justify-center rounded-full mr-2"
@@ -76,7 +76,7 @@
Property' : 'Business' }}</p>
<p class="text-gray-600 mb-2">Located in: {{ listing.location.name ? listing.location.name :
listing.location.county }}, {{ listing.location.state }}</p>
<p class="text-gray-600 mb-2">Price: ${{ $any(listing).price.toLocaleString() }}</p>
<p class="text-gray-600 mb-2">Price: ${{ $any(listing).price ? $any(listing).price.toLocaleString() : 'Price on Request' }}</p>
<div class="flex justify-start">
@if($any(listing).listingsCategory==='business'){
<button class="bg-green-500 text-white w-10 h-10 flex items-center justify-center rounded-full mr-2"

View File

@@ -132,7 +132,7 @@
<h2 class="text-xl font-semibold mb-2">{{ listing.title }}</h2>
<p class="text-gray-600 mb-2">Category: {{ listing.listingsCategory === 'commercialProperty' ? 'Commercial Property' : 'Business' }}</p>
<p class="text-gray-600 mb-2">Located in: {{ listing.location?.name ? listing.location.name : listing.location?.county }} - {{ listing.location?.state }}</p>
<p class="text-gray-600 mb-2">Price: ${{ listing.price.toLocaleString() }}</p>
<p class="text-gray-600 mb-2">Price: ${{ listing.price ? listing.price.toLocaleString() : 'Price on Request' }}</p>
<p class="text-gray-600 mb-2">Internal #: {{ listing.internalListingNumber ?? '—' }}</p>
<div class="flex items-center gap-2 mb-2">
<span class="text-gray-600">Publication Status:</span>