This commit is contained in:
Andreas Knuth 2024-09-11 16:51:42 +02:00
parent 8a7e26d2b6
commit 60866473f7
15 changed files with 135 additions and 117 deletions

View File

@ -1,6 +1,7 @@
import { Controller, Delete, Inject, Param, Post, UploadedFile, UseInterceptors } from '@nestjs/common'; import { Controller, Delete, Inject, Param, Post, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express'; import { FileInterceptor } from '@nestjs/platform-express';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { JwtAuthGuard } from 'src/jwt-auth/jwt-auth.guard';
import { Logger } from 'winston'; import { Logger } from 'winston';
import { FileService } from '../file/file.service'; import { FileService } from '../file/file.service';
import { CommercialPropertyService } from '../listings/commercial-property.service'; import { CommercialPropertyService } from '../listings/commercial-property.service';
@ -17,12 +18,14 @@ export class ImageController {
// ############ // ############
// Property // Property
// ############ // ############
@UseGuards(JwtAuthGuard)
@Post('uploadPropertyPicture/:imagePath/:serial') @Post('uploadPropertyPicture/:imagePath/:serial')
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
async uploadPropertyPicture(@UploadedFile() file: Express.Multer.File, @Param('imagePath') imagePath: string, @Param('serial') serial: string) { async uploadPropertyPicture(@UploadedFile() file: Express.Multer.File, @Param('imagePath') imagePath: string, @Param('serial') serial: string) {
const imagename = await this.fileService.storePropertyPicture(file, imagePath, serial); const imagename = await this.fileService.storePropertyPicture(file, imagePath, serial);
await this.listingService.addImage(imagePath, serial, imagename); await this.listingService.addImage(imagePath, serial, imagename);
} }
@UseGuards(JwtAuthGuard)
@Delete('propertyPicture/:imagePath/:serial/:imagename') @Delete('propertyPicture/:imagePath/:serial/:imagename')
async deletePropertyImagesById(@Param('imagePath') imagePath: string, @Param('serial') serial: string, @Param('imagename') imagename: string): Promise<any> { async deletePropertyImagesById(@Param('imagePath') imagePath: string, @Param('serial') serial: string, @Param('imagename') imagename: string): Promise<any> {
this.fileService.deleteImage(`pictures/property/${imagePath}/${serial}/${imagename}`); this.fileService.deleteImage(`pictures/property/${imagePath}/${serial}/${imagename}`);
@ -31,11 +34,13 @@ export class ImageController {
// ############ // ############
// Profile // Profile
// ############ // ############
@UseGuards(JwtAuthGuard)
@Post('uploadProfile/:email') @Post('uploadProfile/:email')
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
async uploadProfile(@UploadedFile() file: Express.Multer.File, @Param('email') adjustedEmail: string) { async uploadProfile(@UploadedFile() file: Express.Multer.File, @Param('email') adjustedEmail: string) {
await this.fileService.storeProfilePicture(file, adjustedEmail); await this.fileService.storeProfilePicture(file, adjustedEmail);
} }
@UseGuards(JwtAuthGuard)
@Delete('profile/:email/') @Delete('profile/:email/')
async deleteProfileImagesById(@Param('email') email: string): Promise<any> { async deleteProfileImagesById(@Param('email') email: string): Promise<any> {
this.fileService.deleteImage(`pictures/profile/${email}.avif`); this.fileService.deleteImage(`pictures/profile/${email}.avif`);
@ -43,11 +48,13 @@ export class ImageController {
// ############ // ############
// Logo // Logo
// ############ // ############
@UseGuards(JwtAuthGuard)
@Post('uploadCompanyLogo/:email') @Post('uploadCompanyLogo/:email')
@UseInterceptors(FileInterceptor('file')) @UseInterceptors(FileInterceptor('file'))
async uploadCompanyLogo(@UploadedFile() file: Express.Multer.File, @Param('email') adjustedEmail: string) { async uploadCompanyLogo(@UploadedFile() file: Express.Multer.File, @Param('email') adjustedEmail: string) {
await this.fileService.storeCompanyLogo(file, adjustedEmail); await this.fileService.storeCompanyLogo(file, adjustedEmail);
} }
@UseGuards(JwtAuthGuard)
@Delete('logo/:email/') @Delete('logo/:email/')
async deleteLogoImagesById(@Param('email') adjustedEmail: string): Promise<any> { async deleteLogoImagesById(@Param('email') adjustedEmail: string): Promise<any> {
this.fileService.deleteImage(`pictures/logo/${adjustedEmail}.avif`); this.fileService.deleteImage(`pictures/logo/${adjustedEmail}.avif`);

View File

@ -103,9 +103,6 @@ export class BusinessListingService {
whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`))); whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`)));
} }
} }
// if (criteria.brokerName) {
// whereConditions.push(or(ilike(schema.users.firstname, `%${criteria.brokerName}%`), ilike(schema.users.lastname, `%${criteria.brokerName}%`)));
// }
if (!user?.roles?.includes('ADMIN') ?? false) { if (!user?.roles?.includes('ADMIN') ?? false) {
whereConditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true))); whereConditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true)));
} }

View File

@ -51,16 +51,12 @@ export class BusinessListingsController {
this.logger.info(`Save Listing`); this.logger.info(`Save Listing`);
return this.listingsService.updateBusinessListing(listing.id, listing); return this.listingsService.updateBusinessListing(listing.id, listing);
} }
@Delete(':id') @Delete('listing/:id')
deleteById(@Param('id') id: string) { deleteById(@Param('id') id: string) {
this.listingsService.deleteListing(id); this.listingsService.deleteListing(id);
} }
// @Get('states/all')
// getStates(): any {
// return this.listingsService.getStates();
// }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Delete('favorites/:id') @Delete('favorite/:id')
deleteFavorite(@Request() req, @Param('id') id: string) { deleteFavorite(@Request() req, @Param('id') id: string) {
this.listingsService.deleteFavorite(id, req.user as JwtUser); this.listingsService.deleteFavorite(id, req.user as JwtUser);
} }

View File

@ -41,10 +41,6 @@ export class CommercialPropertyListingsController {
findTotal(@Request() req, @Body() criteria: CommercialPropertyListingCriteria): Promise<number> { findTotal(@Request() req, @Body() criteria: CommercialPropertyListingCriteria): Promise<number> {
return this.listingsService.getCommercialPropertiesCount(criteria, req.user as JwtUser); return this.listingsService.getCommercialPropertiesCount(criteria, req.user as JwtUser);
} }
// @Get('states/all')
// getStates(): any {
// return this.listingsService.getStates();
// }
@Post() @Post()
async create(@Body() listing: any) { async create(@Body() listing: any) {
this.logger.info(`Save Listing`); this.logger.info(`Save Listing`);
@ -55,13 +51,13 @@ export class CommercialPropertyListingsController {
this.logger.info(`Save Listing`); this.logger.info(`Save Listing`);
return await this.listingsService.updateCommercialPropertyListing(listing.id, listing); return await this.listingsService.updateCommercialPropertyListing(listing.id, listing);
} }
@Delete(':id/:imagePath') @Delete('listing/:id/:imagePath')
deleteById(@Param('id') id: string, @Param('imagePath') imagePath: string) { deleteById(@Param('id') id: string, @Param('imagePath') imagePath: string) {
this.listingsService.deleteListing(id); this.listingsService.deleteListing(id);
this.fileService.deleteDirectoryIfExists(imagePath); this.fileService.deleteDirectoryIfExists(imagePath);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Delete('favorites/:id') @Delete('favorite/:id')
deleteFavorite(@Request() req, @Param('id') id: string) { deleteFavorite(@Request() req, @Param('id') id: string) {
this.listingsService.deleteFavorite(id, req.user as JwtUser); this.listingsService.deleteFavorite(id, req.user as JwtUser);
} }

View File

@ -115,8 +115,8 @@ export class MailService {
//template: './inquiry', // `.hbs` extension is appended automatically //template: './inquiry', // `.hbs` extension is appended automatically
template: join(__dirname, '../..', 'mail/templates/send2Friend.hbs'), template: join(__dirname, '../..', 'mail/templates/send2Friend.hbs'),
context: { context: {
name: shareByEMail.name, name: shareByEMail.yourName,
email: shareByEMail.email, email: shareByEMail.yourEmail,
listingTitle: shareByEMail.listingTitle, listingTitle: shareByEMail.listingTitle,
url: shareByEMail.url, url: shareByEMail.url,
id: shareByEMail.id, id: shareByEMail.id,

View File

@ -307,9 +307,9 @@ export const SenderSchema = z.object({
}); });
export type Sender = z.infer<typeof SenderSchema>; export type Sender = z.infer<typeof SenderSchema>;
export const ShareByEMailSchema = z.object({ export const ShareByEMailSchema = z.object({
name: z.string().min(6, { message: 'Name must be at least 6 characters long' }), yourName: z.string().min(6, { message: 'Name must be at least 6 characters long' }),
recipientEmail: z.string().email({ message: 'Invalid email address' }), recipientEmail: z.string().email({ message: 'Invalid email address' }),
email: z.string().email({ message: 'Invalid email address' }), yourEmail: z.string().email({ message: 'Invalid email address' }),
listingTitle: z.string().optional().nullable(), listingTitle: z.string().optional().nullable(),
url: z.string().url({ message: 'Invalid URL format' }).optional().nullable(), url: z.string().url({ message: 'Invalid URL format' }).optional().nullable(),
id: z.string().optional().nullable(), id: z.string().optional().nullable(),

View File

@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, HostListener } from '@angular/core'; import { Component, HostListener } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, RouterOutlet } from '@angular/router'; import { ActivatedRoute, NavigationEnd, Router, RouterOutlet } from '@angular/router';
import { KeycloakService } from 'keycloak-angular'; import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
import { filter } from 'rxjs/operators'; import { filter } from 'rxjs/operators';
import build from '../build'; import build from '../build';
@ -45,14 +45,38 @@ export class AppComponent {
this.actualRoute = currentRoute.snapshot.url[0].path; this.actualRoute = currentRoute.snapshot.url[0].path;
}); });
} }
ngOnInit() {} ngOnInit() {
// Überwache Keycloak-Events, um den Token-Refresh zu kontrollieren
this.keycloakService.keycloakEvents$.subscribe({
next: event => {
if (event.type === KeycloakEventType.OnTokenExpired) {
// Wenn der Token abgelaufen ist, versuchen wir einen Refresh
this.handleTokenExpiration();
}
},
});
}
private async handleTokenExpiration(): Promise<void> {
try {
// Versuche, den Token zu erneuern
const refreshed = await this.keycloakService.updateToken();
if (!refreshed) {
// Wenn der Token nicht erneuert werden kann, leite zur Login-Seite weiter
this.keycloakService.login({
redirectUri: window.location.href, // oder eine andere Seite
});
}
} catch (error) {
if (error.error === 'invalid_grant' && error.error_description === 'Token is not active') {
// Hier wird der Fehler "invalid_grant" abgefangen
this.keycloakService.login({
redirectUri: window.location.href,
});
}
}
}
@HostListener('window:keydown', ['$event']) @HostListener('window:keydown', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) { handleKeyboardEvent(event: KeyboardEvent) {
// this.router.events.subscribe(event => {
// if (event instanceof NavigationEnd) {
// initFlowbite();
// }
// });
if (event.shiftKey && event.ctrlKey && event.key === 'V') { if (event.shiftKey && event.ctrlKey && event.key === 'V') {
this.showVersionDialog(); this.showVersionDialog();
} }

View File

@ -1,4 +1,4 @@
import { APP_INITIALIZER, ApplicationConfig } from '@angular/core'; import { APP_INITIALIZER, ApplicationConfig, ErrorHandler } from '@angular/core';
import { provideRouter, withEnabledBlockingInitialNavigation, withInMemoryScrolling } from '@angular/router'; import { provideRouter, withEnabledBlockingInitialNavigation, withInMemoryScrolling } from '@angular/router';
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
@ -9,11 +9,10 @@ import { provideQuillConfig } from 'ngx-quill';
import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons'; import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons';
import { shareIcons } from 'ngx-sharebuttons/icons'; import { shareIcons } from 'ngx-sharebuttons/icons';
import { provideNgxStripe } from 'ngx-stripe'; import { provideNgxStripe } from 'ngx-stripe';
import { environment } from '../environments/environment';
import { customKeycloakAdapter } from '../keycloak';
import { routes } from './app.routes'; import { routes } from './app.routes';
import { LoadingInterceptor } from './interceptors/loading.interceptor'; import { LoadingInterceptor } from './interceptors/loading.interceptor';
import { TimeoutInterceptor } from './interceptors/timeout.interceptor'; import { TimeoutInterceptor } from './interceptors/timeout.interceptor';
import { GlobalErrorHandler } from './services/globalErrorHandler';
import { KeycloakInitializerService } from './services/keycloak-initializer.service'; import { KeycloakInitializerService } from './services/keycloak-initializer.service';
import { SelectOptionsService } from './services/select-options.service'; import { SelectOptionsService } from './services/select-options.service';
import { createLogger } from './utils/utils'; import { createLogger } from './utils/utils';
@ -25,9 +24,9 @@ export const appConfig: ApplicationConfig = {
{ provide: KeycloakService }, { provide: KeycloakService },
{ {
provide: APP_INITIALIZER, provide: APP_INITIALIZER,
// useFactory: initializeKeycloak, // useFactory: initializeKeycloak1,
//useFactory: initializeKeycloak, //useFactory: initializeKeycloak2,
useFactory: initializeKeycloak3, useFactory: initializeKeycloak,
multi: true, multi: true,
//deps: [KeycloakService], //deps: [KeycloakService],
deps: [KeycloakInitializerService], deps: [KeycloakInitializerService],
@ -64,6 +63,7 @@ export const appConfig: ApplicationConfig = {
imageSize: 'cover', imageSize: 'cover',
} as GalleryConfig, } as GalleryConfig,
}, },
{ provide: ErrorHandler, useClass: GlobalErrorHandler }, // Registriere den globalen ErrorHandler
provideShareButtonsOptions( provideShareButtonsOptions(
shareIcons(), shareIcons(),
withConfig({ withConfig({
@ -100,47 +100,47 @@ function initServices(selectOptions: SelectOptionsService) {
await selectOptions.init(); await selectOptions.init();
}; };
} }
export function initializeKeycloak3(keycloak: KeycloakInitializerService) { export function initializeKeycloak(keycloak: KeycloakInitializerService) {
return () => keycloak.initialize(); return () => keycloak.initialize();
} }
export function initializeKeycloak2(keycloak: KeycloakService): () => Promise<void> { // export function initializeKeycloak1(keycloak: KeycloakService): () => Promise<void> {
return async () => { // return async () => {
const { url, realm, clientId } = environment.keycloak; // const { url, realm, clientId } = environment.keycloak;
const adapter = customKeycloakAdapter(() => keycloak.getKeycloakInstance(), {}); // const adapter = customKeycloakAdapter(() => keycloak.getKeycloakInstance(), {});
if (window.location.search.length > 0) { // if (window.location.search.length > 0) {
sessionStorage.setItem('SEARCH', window.location.search); // sessionStorage.setItem('SEARCH', window.location.search);
} // }
const { host, hostname, href, origin, pathname, port, protocol, search } = window.location; // const { host, hostname, href, origin, pathname, port, protocol, search } = window.location;
await keycloak.init({ // await keycloak.init({
config: { url, realm, clientId }, // config: { url, realm, clientId },
initOptions: { // initOptions: {
onLoad: 'check-sso', // onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.hostname === 'localhost' ? `${window.location.origin}/assets/silent-check-sso.html` : `${window.location.origin}/dealerweb/assets/silent-check-sso.html`, // silentCheckSsoRedirectUri: window.location.hostname === 'localhost' ? `${window.location.origin}/assets/silent-check-sso.html` : `${window.location.origin}/dealerweb/assets/silent-check-sso.html`,
adapter, // adapter,
redirectUri: `${origin}${pathname}`, // redirectUri: `${origin}${pathname}`,
}, // },
}); // });
}; // };
} // }
function initializeKeycloak(keycloak: KeycloakService) { // function initializeKeycloak2(keycloak: KeycloakService) {
return async () => { // return async () => {
logger.info(`###>calling keycloakService init ...`); // logger.info(`###>calling keycloakService init ...`);
const authenticated = await keycloak.init({ // const authenticated = await keycloak.init({
config: { // config: {
url: environment.keycloak.url, // url: environment.keycloak.url,
realm: environment.keycloak.realm, // realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId, // clientId: environment.keycloak.clientId,
}, // },
initOptions: { // initOptions: {
onLoad: 'check-sso', // onLoad: 'check-sso',
silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html', // silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html',
}, // },
bearerExcludedUrls: ['/assets'], // bearerExcludedUrls: ['/assets'],
shouldUpdateToken(request) { // shouldUpdateToken(request) {
return !request.headers.get('token-update') === false; // return !request.headers.get('token-update') === false;
}, // },
}); // });
logger.info(`+++>${authenticated}`); // logger.info(`+++>${authenticated}`);
}; // };
} // }

View File

@ -21,10 +21,10 @@
<div class="p-4 md:p-5"> <div class="p-4 md:p-5">
<form class="space-y-4" action="#"> <form class="space-y-4" action="#">
<div> <div>
<app-validated-input label="Your Email" name="email" [(ngModel)]="shareByEMail.email"></app-validated-input> <app-validated-input label="Your Email" name="yourEmail" [(ngModel)]="shareByEMail.yourEmail"></app-validated-input>
</div> </div>
<div> <div>
<app-validated-input label="Your Name" name="name" [(ngModel)]="shareByEMail.name"></app-validated-input> <app-validated-input label="Your Name" name="yourName" [(ngModel)]="shareByEMail.yourName"></app-validated-input>
</div> </div>
<div> <div>
<app-validated-input label="Your Friend's EMail" name="recipientEmail" [(ngModel)]="shareByEMail.recipientEmail"></app-validated-input> <app-validated-input label="Your Friend's EMail" name="recipientEmail" [(ngModel)]="shareByEMail.recipientEmail"></app-validated-input>

View File

@ -1,7 +1,7 @@
<div <div
[id]="id" [id]="id"
role="tooltip" role="tooltip"
class="max-w-72 w-max absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700" class="max-w-72 w-max absolute z-50 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"
> >
{{ text }} {{ text }}
<div class="tooltip-arrow" data-popper-arrow></div> <div class="tooltip-arrow" data-popper-arrow></div>

View File

@ -110,7 +110,6 @@ export class DetailsBusinessListingComponent {
this.mailinfo.listing = this.listing; this.mailinfo.listing = this.listing;
await this.mailService.mail(this.mailinfo); await this.mailService.mail(this.mailinfo);
this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 }); this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 });
this.mailinfo = createMailInfo(this.user);
} catch (error) { } catch (error) {
this.messageService.addMessage({ this.messageService.addMessage({
severity: 'danger', severity: 'danger',
@ -121,6 +120,9 @@ export class DetailsBusinessListingComponent {
this.validationMessagesService.updateMessages(error.error.message); this.validationMessagesService.updateMessages(error.error.message);
} }
} }
if (this.user) {
this.mailinfo = createMailInfo(this.user);
}
} }
get listingDetails() { get listingDetails() {
let typeOfRealEstate = ''; let typeOfRealEstate = '';
@ -158,8 +160,8 @@ export class DetailsBusinessListingComponent {
} }
async showShareByEMail() { async showShareByEMail() {
const result = await this.emailService.showShareByEMail({ const result = await this.emailService.showShareByEMail({
email: this.user.email, yourEmail: this.user ? this.user.email : null,
name: `${this.user.firstname} ${this.user.lastname}`, yourName: this.user ? `${this.user.firstname} ${this.user.lastname}` : null,
url: environment.mailinfoUrl, url: environment.mailinfoUrl,
listingTitle: this.listing.title, listingTitle: this.listing.title,
id: this.listing.id, id: this.listing.id,

View File

@ -143,7 +143,6 @@ export class DetailsCommercialPropertyListingComponent {
this.mailinfo.listing = this.listing; this.mailinfo.listing = this.listing;
await this.mailService.mail(this.mailinfo); await this.mailService.mail(this.mailinfo);
this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 }); this.messageService.addMessage({ severity: 'success', text: 'Your message has been sent to the creator of the listing', duration: 3000 });
this.mailinfo = createMailInfo(this.user);
} catch (error) { } catch (error) {
this.messageService.addMessage({ this.messageService.addMessage({
severity: 'danger', severity: 'danger',
@ -154,6 +153,9 @@ export class DetailsCommercialPropertyListingComponent {
this.validationMessagesService.updateMessages(error.error.message); this.validationMessagesService.updateMessages(error.error.message);
} }
} }
if (this.user) {
this.mailinfo = createMailInfo(this.user);
}
} }
containsError(fieldname: string) { containsError(fieldname: string) {
return this.errorResponse?.fields.map(f => f.fieldname).includes(fieldname); return this.errorResponse?.fields.map(f => f.fieldname).includes(fieldname);
@ -170,8 +172,8 @@ export class DetailsCommercialPropertyListingComponent {
} }
async showShareByEMail() { async showShareByEMail() {
const result = await this.emailService.showShareByEMail({ const result = await this.emailService.showShareByEMail({
email: this.user.email, yourEmail: this.user.email,
name: `${this.user.firstname} ${this.user.lastname}`, yourName: `${this.user.firstname} ${this.user.lastname}`,
url: environment.mailinfoUrl, url: environment.mailinfoUrl,
listingTitle: this.listing.title, listingTitle: this.listing.title,
id: this.listing.id, id: this.listing.id,

View File

@ -0,0 +1,24 @@
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHandler, Injectable } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
constructor(private keycloakService: KeycloakService) {}
handleError(error: any): void {
// Prüfe, ob es sich um einen HttpErrorResponse handelt
if (error instanceof HttpErrorResponse) {
// Prüfe, ob es ein 401 Unauthorized Fehler ist
if (error.status === 401) {
// Führe den Login-Prozess über Keycloak aus
this.keycloakService.login({
redirectUri: window.location.href, // oder eine benutzerdefinierte URL
});
}
}
// Weiterhin normale Fehlerbehandlung
console.error('Ein Fehler ist aufgetreten:', error);
}
}

View File

@ -21,8 +21,8 @@ export class KeycloakInitializerService {
initOptions: { initOptions: {
onLoad: 'check-sso', onLoad: 'check-sso',
silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html', silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html',
// flow: 'implicit',
}, },
bearerExcludedUrls: ['/assets'],
}); });
this.initialized = true; this.initialized = true;
resolve(true); resolve(true);
@ -30,35 +30,5 @@ export class KeycloakInitializerService {
reject(error); reject(error);
} }
}); });
// if (this.initialized) {
// return;
// }
// logger.info(`###>calling keycloakService init ...`);
// const authenticated = await this.keycloakService.init({
// config: {
// url: environment.keycloak.url,
// realm: environment.keycloak.realm,
// clientId: environment.keycloak.clientId,
// },
// initOptions: {
// onLoad: 'check-sso',
// silentCheckSsoRedirectUri: (<any>window).location.origin + '/assets/silent-check-sso.html',
// // flow: 'implicit',
// },
// // initOptions: {
// // pkceMethod: 'S256',
// // redirectUri: environment.keycloak.redirectUri,
// // checkLoginIframe: false,
// // },
// });
// logger.info(`+++>authenticated: ${authenticated}`);
// const token = await this.keycloakService.getToken();
// logger.info(`--->${token}`);
// this.initialized = true;
} }
// isInitialized(): boolean {
// return this.initialized;
// }
} }

View File

@ -44,12 +44,12 @@ export class ListingsService {
} }
} }
async deleteBusinessListing(id: string) { async deleteBusinessListing(id: string) {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/business/${id}`)); await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/business/listing/${id}`));
} }
async deleteCommercialPropertyListing(id: string, imagePath: string) { async deleteCommercialPropertyListing(id: string, imagePath: string) {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/commercialProperty/${id}/${imagePath}`)); await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/commercialProperty/listing/${id}/${imagePath}`));
} }
async removeFavorite(id: string, listingsCategory?: 'business' | 'commercialProperty') { async removeFavorite(id: string, listingsCategory?: 'business' | 'commercialProperty') {
await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/favorites/${id}`)); await lastValueFrom(this.http.delete<ListingType>(`${this.apiBaseUrl}/bizmatch/listings/${listingsCategory}/favorite/${id}`));
} }
} }