acc. draft mode, take care of ADMIN role or on own listings

This commit is contained in:
Andreas Knuth 2024-05-28 13:15:31 -05:00
parent 44acbcd4d0
commit 902ab9caed
4 changed files with 41 additions and 14 deletions

View File

@ -25,9 +25,10 @@ export class BusinessListingsController {
return this.listingsService.findBusinessesByEmail(userid, req.user as JwtUser); return this.listingsService.findBusinessesByEmail(userid, req.user as JwtUser);
} }
@UseGuards(OptionalJwtAuthGuard)
@Post('search') @Post('search')
find(@Body() criteria: ListingCriteria): any { find(@Request() req, @Body() criteria: ListingCriteria): any {
return this.listingsService.findListingsByCriteria(criteria, businesses); return this.listingsService.findBusinessListings(criteria, req.user as JwtUser);
} }
@Post() @Post()

View File

@ -27,9 +27,10 @@ export class CommercialPropertyListingsController {
findByEmail(@Request() req, @Param('email') email: string): Promise<CommercialPropertyListing[]> { findByEmail(@Request() req, @Param('email') email: string): Promise<CommercialPropertyListing[]> {
return this.listingsService.findCommercialPropertiesByEmail(email, req.user as JwtUser); return this.listingsService.findCommercialPropertiesByEmail(email, req.user as JwtUser);
} }
@UseGuards(OptionalJwtAuthGuard)
@Post('search') @Post('search')
async find(@Body() criteria: ListingCriteria): Promise<any> { async find(@Request() req, @Body() criteria: ListingCriteria): Promise<any> {
return await this.listingsService.findListingsByCriteria(criteria, commercials); return await this.listingsService.findCommercialPropertyListings(criteria, req.user as JwtUser);
} }
@Get('states/all') @Get('states/all')
getStates(): any { getStates(): any {

View File

@ -1,5 +1,5 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { and, eq, gte, ilike, lte, ne, sql } from 'drizzle-orm'; import { and, eq, gte, ilike, lte, ne, or, sql } from 'drizzle-orm';
import { NodePgDatabase } from 'drizzle-orm/node-postgres'; import { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { BusinessListing, CommercialPropertyListing } from 'src/models/db.model.js'; import { BusinessListing, CommercialPropertyListing } from 'src/models/db.model.js';
@ -16,9 +16,8 @@ export class ListingsService {
@Inject(PG_CONNECTION) private conn: NodePgDatabase<typeof schema>, @Inject(PG_CONNECTION) private conn: NodePgDatabase<typeof schema>,
private fileService: FileService, private fileService: FileService,
) {} ) {}
private getConditions(criteria: ListingCriteria, table: typeof businesses | typeof commercials): any[] { private getConditions(criteria: ListingCriteria, table: typeof businesses | typeof commercials, user: JwtUser): any[] {
const conditions = []; const conditions = [];
conditions.push(ne(table.draft, true));
if (criteria.type) { if (criteria.type) {
conditions.push(eq(table.type, criteria.type)); conditions.push(eq(table.type, criteria.type));
} }
@ -42,23 +41,46 @@ export class ListingsService {
// ############################################################## // ##############################################################
// Listings general // Listings general
// ############################################################## // ##############################################################
async findListingsByCriteria(criteria: ListingCriteria, table: typeof businesses | typeof commercials): Promise<{ data: Record<string, any>[]; total: number }> {
async findCommercialPropertyListings(criteria: ListingCriteria, user: JwtUser): Promise<any> {
const start = criteria.start ? criteria.start : 0; const start = criteria.start ? criteria.start : 0;
const length = criteria.length ? criteria.length : 12; const length = criteria.length ? criteria.length : 12;
return await this.findListings(table, criteria, start, length); const conditions = this.getConditions(criteria, commercials, user);
if (!user || (!user?.roles?.includes('ADMIN') ?? false)) {
conditions.push(or(eq(commercials.draft, false), eq(commercials.imagePath, emailToDirName(user?.username))));
} }
private async findListings(table: typeof businesses | typeof commercials, criteria: ListingCriteria, start = 0, length = 12): Promise<any> {
const conditions = this.getConditions(criteria, table);
const [data, total] = await Promise.all([ const [data, total] = await Promise.all([
this.conn this.conn
.select() .select()
.from(table) .from(commercials)
.where(and(...conditions)) .where(and(...conditions))
.offset(start) .offset(start)
.limit(length), .limit(length),
this.conn this.conn
.select({ count: sql`count(*)` }) .select({ count: sql`count(*)` })
.from(table) .from(commercials)
.where(and(...conditions))
.then(result => Number(result[0].count)),
]);
return { total, data };
}
async findBusinessListings(criteria: ListingCriteria, user: JwtUser): Promise<any> {
const start = criteria.start ? criteria.start : 0;
const length = criteria.length ? criteria.length : 12;
const conditions = this.getConditions(criteria, businesses, user);
if (!user || (!user?.roles?.includes('ADMIN') ?? false)) {
conditions.push(or(eq(businesses.draft, false), eq(businesses.imageName, emailToDirName(user?.username))));
}
const [data, total] = await Promise.all([
this.conn
.select()
.from(businesses)
.where(and(...conditions))
.offset(start)
.limit(length),
this.conn
.select({ count: sql`count(*)` })
.from(businesses)
.where(and(...conditions)) .where(and(...conditions))
.then(result => Number(result[0].count)), .then(result => Number(result[0].count)),
]); ]);

View File

@ -198,6 +198,9 @@ export function isEmpty(value: any): boolean {
return false; return false;
} }
export function emailToDirName(email: string): string { export function emailToDirName(email: string): string {
if (email === undefined || email === null) {
return null;
}
// Entferne ungültige Zeichen und ersetze sie durch Unterstriche // Entferne ungültige Zeichen und ersetze sie durch Unterstriche
const sanitizedEmail = email.replace(/[^a-zA-Z0-9_-]/g, '_'); const sanitizedEmail = email.replace(/[^a-zA-Z0-9_-]/g, '_');