diff --git a/bizmatch-server/package.json b/bizmatch-server/package.json index ed01bf1..461bb10 100644 --- a/bizmatch-server/package.json +++ b/bizmatch-server/package.json @@ -47,6 +47,7 @@ "fs-extra": "^11.2.0", "groq-sdk": "^0.5.0", "handlebars": "^4.7.8", + "helmet": "^8.1.0", "nest-winston": "^1.9.4", "nestjs-cls": "^5.4.0", "nodemailer": "^7.0.12", @@ -109,4 +110,4 @@ "coverageDirectory": "../coverage", "testEnvironment": "node" } -} \ No newline at end of file +} diff --git a/bizmatch-server/src/main.ts b/bizmatch-server/src/main.ts index 657ac6b..760275b 100644 --- a/bizmatch-server/src/main.ts +++ b/bizmatch-server/src/main.ts @@ -1,6 +1,7 @@ import { LoggerService } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import express from 'express'; +import helmet from 'helmet'; import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston'; import { AppModule } from './app.module'; @@ -22,6 +23,37 @@ async function bootstrap() { methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', allowedHeaders: 'Content-Type, Accept, Authorization, x-hide-loading', }); + + // Security Headers with helmet + app.use( + helmet({ + contentSecurityPolicy: { + directives: { + defaultSrc: ["'self'"], + scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://fonts.googleapis.com"], + styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"], + imgSrc: ["'self'", "data:", "https:", "blob:"], + connectSrc: ["'self'", "https://api.bizmatch.net", "https://*.firebaseapp.com", "https://*.googleapis.com"], + fontSrc: ["'self'", "https://fonts.gstatic.com", "data:"], + objectSrc: ["'none'"], + mediaSrc: ["'self'"], + frameSrc: ["'self'"], + }, + }, + crossOriginEmbedderPolicy: false, // Disable for now to avoid breaking existing functionality + hsts: { + maxAge: 31536000, + includeSubDomains: true, + preload: true, + }, + frameguard: { + action: 'sameorigin', // Allow same-origin framing + }, + crossOriginOpenerPolicy: { policy: 'same-origin-allow-popups' }, // Allow popups for OAuth + crossOriginResourcePolicy: { policy: 'cross-origin' }, // Allow cross-origin resources + }), + ); + await app.listen(process.env.PORT || 3001); } bootstrap(); diff --git a/bizmatch/angular.json b/bizmatch/angular.json index b9b8b2b..eb621ff 100644 --- a/bizmatch/angular.json +++ b/bizmatch/angular.json @@ -21,11 +21,6 @@ "outputPath": "dist/bizmatch", "index": "src/index.html", "browser": "src/main.ts", - "server": "src/main.server.ts", - "prerender": false, - "ssr": { - "entry": "server.ts" - }, "allowedCommonJsDependencies": [ "quill-delta", "leaflet", @@ -53,10 +48,7 @@ ], "styles": [ "src/styles.scss", - "src/styles/lazy-load.css", - "node_modules/quill/dist/quill.snow.css", - "node_modules/leaflet/dist/leaflet.css", - "node_modules/ngx-sharebuttons/themes/default.scss" + "src/styles/lazy-load.css" ] }, "configurations": { @@ -69,8 +61,8 @@ }, { "type": "anyComponentStyle", - "maximumWarning": "2kb", - "maximumError": "4kb" + "maximumWarning": "10kb", + "maximumError": "30kb" } ], "outputHashing": "all" @@ -78,8 +70,7 @@ "development": { "optimization": false, "extractLicenses": false, - "sourceMap": true, - "ssr": false + "sourceMap": true }, "dev": { "fileReplacements": [ diff --git a/bizmatch/src/app/app.config.ts b/bizmatch/src/app/app.config.ts index cf058a2..f15e4d9 100644 --- a/bizmatch/src/app/app.config.ts +++ b/bizmatch/src/app/app.config.ts @@ -7,10 +7,6 @@ import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@a import { initializeApp, provideFirebaseApp } from '@angular/fire/app'; import { getAuth, provideAuth } from '@angular/fire/auth'; import { provideAnimations } from '@angular/platform-browser/animations'; -import { GALLERY_CONFIG, GalleryConfig } from 'ng-gallery'; -import { provideQuillConfig } from 'ngx-quill'; -import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons'; -import { shareIcons } from 'ngx-sharebuttons/icons'; import { environment } from '../environments/environment'; import { routes } from './app.routes'; import { AuthInterceptor } from './interceptors/auth.interceptor'; @@ -48,13 +44,6 @@ export const appConfig: ApplicationConfig = { provide: 'TIMEOUT_DURATION', useValue: 5000, // Standard-Timeout von 5 Sekunden }, - { - provide: GALLERY_CONFIG, - useValue: { - autoHeight: true, - imageSize: 'cover', - } as GalleryConfig, - }, { provide: ErrorHandler, useClass: GlobalErrorHandler }, // Registriere den globalen ErrorHandler { provide: IMAGE_CONFIG, @@ -62,13 +51,6 @@ export const appConfig: ApplicationConfig = { disableImageSizeWarning: true, }, }, - provideShareButtonsOptions( - shareIcons(), - withConfig({ - debug: true, - sharerMethod: SharerMethods.Anchor, - }), - ), provideRouter( routes, withEnabledBlockingInitialNavigation(), @@ -79,18 +61,6 @@ export const appConfig: ApplicationConfig = { ), ...(environment.production ? [POSTHOG_INIT_PROVIDER] : []), provideAnimations(), - provideQuillConfig({ - modules: { - syntax: true, - toolbar: [ - ['bold', 'italic', 'underline'], // Einige Standardoptionen - [{ header: [1, 2, 3, false] }], // Benutzerdefinierte Header - [{ list: 'ordered' }, { list: 'bullet' }], - [{ color: [] }], // Dropdown mit Standardfarben - ['clean'], // Entfernt Formatierungen - ], - }, - }), provideFirebaseApp(() => initializeApp(environment.firebaseConfig)), provideAuth(() => getAuth()), ], diff --git a/bizmatch/src/app/components/confirmation/confirmation.component.ts b/bizmatch/src/app/components/confirmation/confirmation.component.ts index 04606f0..8e66a6a 100644 --- a/bizmatch/src/app/components/confirmation/confirmation.component.ts +++ b/bizmatch/src/app/components/confirmation/confirmation.component.ts @@ -13,7 +13,7 @@ import { ConfirmationService } from './confirmation.service';
-

{{ confirmation?.message }}

+

{{ confirmation?.message }}

@if(confirmation?.buttons==='both'){ diff --git a/bizmatch/src/app/components/email/email.component.html b/bizmatch/src/app/components/email/email.component.html index a68bcbb..15ced7a 100644 --- a/bizmatch/src/app/components/email/email.component.html +++ b/bizmatch/src/app/components/email/email.component.html @@ -9,7 +9,7 @@
@@ -65,7 +65,7 @@ placeholder="Repeat Password" class="w-full px-3 py-2 pl-10 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" /> - + diff --git a/bizmatch/src/app/components/login-register/login-register.component.ts b/bizmatch/src/app/components/login-register/login-register.component.ts index af9bada..faf6e29 100644 --- a/bizmatch/src/app/components/login-register/login-register.component.ts +++ b/bizmatch/src/app/components/login-register/login-register.component.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { faArrowRight, faEnvelope, faLock, faUserPlus } from '@fortawesome/free-solid-svg-icons'; +import { APP_ICONS } from '../../utils/fontawesome-icons'; import { AuthService } from '../../services/auth.service'; import { LoadingService } from '../../services/loading.service'; @Component({ @@ -18,10 +18,10 @@ export class LoginRegisterComponent { confirmPassword: string = ''; isLoginMode: boolean = true; // true: Login, false: Registration errorMessage: string = ''; - envelope = faEnvelope; - lock = faLock; - arrowRight = faArrowRight; - userplus = faUserPlus; + envelope = APP_ICONS.faEnvelope; + lock = APP_ICONS.faLock; + arrowRight = APP_ICONS.faArrowRight; + userplus = APP_ICONS.faUserPlus; constructor(private authService: AuthService, private route: ActivatedRoute, private router: Router, private loadingService: LoadingService) {} ngOnInit(): void { diff --git a/bizmatch/src/app/components/search-modal/search-modal-broker.component.html b/bizmatch/src/app/components/search-modal/search-modal-broker.component.html index 4058958..6dce6d2 100644 --- a/bizmatch/src/app/components/search-modal/search-modal-broker.component.html +++ b/bizmatch/src/app/components/search-modal/search-modal-broker.component.html @@ -48,7 +48,7 @@
- +
@@ -172,7 +172,7 @@
- +
diff --git a/bizmatch/src/app/components/search-modal/search-modal-commercial.component.html b/bizmatch/src/app/components/search-modal/search-modal-commercial.component.html index 994e3e8..4bb2346 100644 --- a/bizmatch/src/app/components/search-modal/search-modal-commercial.component.html +++ b/bizmatch/src/app/components/search-modal/search-modal-commercial.component.html @@ -48,7 +48,7 @@
- +
@@ -168,7 +168,7 @@
- +
diff --git a/bizmatch/src/app/components/search-modal/search-modal.component.html b/bizmatch/src/app/components/search-modal/search-modal.component.html index 87e646a..b46c57e 100644 --- a/bizmatch/src/app/components/search-modal/search-modal.component.html +++ b/bizmatch/src/app/components/search-modal/search-modal.component.html @@ -61,8 +61,8 @@
- - + +
@@ -266,7 +266,7 @@
- +
diff --git a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts index 7baa6c5..6cce347 100644 --- a/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts +++ b/bizmatch/src/app/pages/details/details-business-listing/details-business-listing.component.ts @@ -31,13 +31,27 @@ import dayjs from 'dayjs'; import { AuthService } from '../../../services/auth.service'; import { BaseDetailsComponent } from '../base-details.component'; import { ShareButton } from 'ngx-sharebuttons/button'; +import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons'; +import { shareIcons } from 'ngx-sharebuttons/icons'; @Component({ selector: 'app-details-business-listing', standalone: true, imports: [SharedModule, ValidatedInputComponent, ValidatedTextareaComponent, ValidatedNgSelectComponent, LeafletModule, BreadcrumbsComponent, ShareButton, NgOptimizedImage], - providers: [], + providers: [ + provideShareButtonsOptions( + shareIcons(), + withConfig({ + debug: false, + sharerMethod: SharerMethods.Anchor, + }), + ), + ], templateUrl: './details-business-listing.component.html', - styleUrl: '../details.scss', + styleUrls: [ + '../details.scss', + '../../../../../node_modules/leaflet/dist/leaflet.css', + '../../../../../node_modules/ngx-sharebuttons/themes/default.scss' + ], }) export class DetailsBusinessListingComponent extends BaseDetailsComponent { // listings: Array; diff --git a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts index dde90a5..895e433 100644 --- a/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/details/details-commercial-property-listing/details-commercial-property-listing.component.ts @@ -3,9 +3,9 @@ import { NgOptimizedImage } from '@angular/common'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; import { LeafletModule } from '@bluehalo/ngx-leaflet'; -import { faTimes } from '@fortawesome/free-solid-svg-icons'; +import { APP_ICONS } from '../../../utils/fontawesome-icons'; import dayjs from 'dayjs'; -import { GalleryModule, ImageItem } from 'ng-gallery'; +import { GALLERY_CONFIG, GalleryConfig, GalleryModule, ImageItem } from 'ng-gallery'; import { lastValueFrom } from 'rxjs'; import { CommercialPropertyListing, EventTypeEnum, ShareByEMail, User } from '../../../../../../bizmatch-server/src/models/db.model'; import { CommercialPropertyListingCriteria, ErrorResponse, KeycloakUser, MailInfo } from '../../../../../../bizmatch-server/src/models/main.model'; @@ -30,14 +30,35 @@ import { createMailInfo, map2User } from '../../../utils/utils'; import { BaseDetailsComponent } from '../base-details.component'; import { BreadcrumbItem, BreadcrumbsComponent } from '../../../components/breadcrumbs/breadcrumbs.component'; import { ShareButton } from 'ngx-sharebuttons/button'; +import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons'; +import { shareIcons } from 'ngx-sharebuttons/icons'; @Component({ selector: 'app-details-commercial-property-listing', standalone: true, imports: [SharedModule, ValidatedInputComponent, ValidatedTextareaComponent, ValidatedNgSelectComponent, GalleryModule, LeafletModule, BreadcrumbsComponent, ShareButton, NgOptimizedImage], - providers: [], + providers: [ + provideShareButtonsOptions( + shareIcons(), + withConfig({ + debug: false, + sharerMethod: SharerMethods.Anchor, + }), + ), + { + provide: GALLERY_CONFIG, + useValue: { + autoHeight: true, + imageSize: 'cover', + } as GalleryConfig, + }, + ], templateUrl: './details-commercial-property-listing.component.html', - styleUrl: '../details.scss', + styleUrls: [ + '../details.scss', + '../../../../../node_modules/leaflet/dist/leaflet.css', + '../../../../../node_modules/ngx-sharebuttons/themes/default.scss' + ], }) export class DetailsCommercialPropertyListingComponent extends BaseDetailsComponent { responsiveOptions = [ @@ -69,7 +90,7 @@ export class DetailsCommercialPropertyListingComponent extends BaseDetailsCompon ts = new Date().getTime(); env = environment; errorResponse: ErrorResponse; - faTimes = faTimes; + faTimes = APP_ICONS.faTimes; propertyDetails = []; images: Array = []; relatedListings: CommercialPropertyListing[] = []; diff --git a/bizmatch/src/app/pages/details/details-user/details-user.component.ts b/bizmatch/src/app/pages/details/details-user/details-user.component.ts index f326e83..fa30428 100644 --- a/bizmatch/src/app/pages/details/details-user/details-user.component.ts +++ b/bizmatch/src/app/pages/details/details-user/details-user.component.ts @@ -19,13 +19,27 @@ import { UserService } from '../../../services/user.service'; import { SharedModule } from '../../../shared/shared/shared.module'; import { formatPhoneNumber, map2User } from '../../../utils/utils'; import { ShareButton } from 'ngx-sharebuttons/button'; +import { provideShareButtonsOptions, SharerMethods, withConfig } from 'ngx-sharebuttons'; +import { shareIcons } from 'ngx-sharebuttons/icons'; @Component({ selector: 'app-details-user', standalone: true, imports: [SharedModule, BreadcrumbsComponent, NgOptimizedImage, ShareButton], + providers: [ + provideShareButtonsOptions( + shareIcons(), + withConfig({ + debug: false, + sharerMethod: SharerMethods.Anchor, + }), + ), + ], templateUrl: './details-user.component.html', - styleUrl: '../details.scss', + styleUrls: [ + '../details.scss', + '../../../../../node_modules/ngx-sharebuttons/themes/default.scss' + ], }) export class DetailsUserComponent { private id: string | undefined = this.activatedRoute.snapshot.params['id'] as string | undefined; diff --git a/bizmatch/src/app/pages/subscription/account/account.component.ts b/bizmatch/src/app/pages/subscription/account/account.component.ts index 902093c..1e62cfc 100644 --- a/bizmatch/src/app/pages/subscription/account/account.component.ts +++ b/bizmatch/src/app/pages/subscription/account/account.component.ts @@ -1,9 +1,9 @@ import { DatePipe, TitleCasePipe } from '@angular/common'; import { ChangeDetectorRef, Component } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { faTrash } from '@fortawesome/free-solid-svg-icons'; +import { APP_ICONS } from '../../../utils/fontawesome-icons'; import { NgSelectModule } from '@ng-select/ng-select'; -import { QuillModule } from 'ngx-quill'; +import { QuillModule, provideQuillConfig } from 'ngx-quill'; import { lastValueFrom } from 'rxjs'; import { User } from '../../../../../../bizmatch-server/src/models/db.model'; import { AutoCompleteCompleteEvent, Invoice, UploadParams, ValidationMessage, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model'; @@ -45,9 +45,27 @@ import { TOOLBAR_OPTIONS } from '../../utils/defaults'; ValidatedCountyComponent, ValidatedLocationComponent, ], - providers: [TitleCasePipe, DatePipe], + providers: [ + TitleCasePipe, + DatePipe, + provideQuillConfig({ + modules: { + syntax: true, + toolbar: [ + ['bold', 'italic', 'underline'], + [{ header: [1, 2, 3, false] }], + [{ list: 'ordered' }, { list: 'bullet' }], + [{ color: [] }], + ['clean'], + ], + }, + }) as any, + ], templateUrl: './account.component.html', - styleUrl: './account.component.scss', + styleUrls: [ + './account.component.scss', + '../../../../../node_modules/quill/dist/quill.snow.css' + ], }) export class AccountComponent { id: string | undefined = this.activatedRoute.snapshot.params['id'] as string | undefined; @@ -58,7 +76,7 @@ export class AccountComponent { environment = environment; editorModules = TOOLBAR_OPTIONS; env = environment; - faTrash = faTrash; + faTrash = APP_ICONS.faTrash; quillModules = { toolbar: [['bold', 'italic', 'underline', 'strike'], [{ list: 'ordered' }, { list: 'bullet' }], [{ header: [1, 2, 3, 4, 5, 6, false] }], [{ color: [] }, { background: [] }], ['clean']], }; diff --git a/bizmatch/src/app/pages/subscription/edit-business-listing/edit-business-listing.component.ts b/bizmatch/src/app/pages/subscription/edit-business-listing/edit-business-listing.component.ts index f75a2ef..380fcac 100644 --- a/bizmatch/src/app/pages/subscription/edit-business-listing/edit-business-listing.component.ts +++ b/bizmatch/src/app/pages/subscription/edit-business-listing/edit-business-listing.component.ts @@ -6,11 +6,12 @@ import { SelectOptionsService } from '../../../services/select-options.service'; import { map2User, routeListingWithState } from '../../../utils/utils'; import { DragDropModule } from '@angular/cdk/drag-drop'; -import { faTrash } from '@fortawesome/free-solid-svg-icons'; +import { APP_ICONS } from '../../../utils/fontawesome-icons'; import { QuillModule } from 'ngx-quill'; import { NgSelectModule } from '@ng-select/ng-select'; import { NgxCurrencyDirective } from 'ngx-currency'; +import { provideQuillConfig } from 'ngx-quill'; import { BusinessListing, CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model'; import { AutoCompleteCompleteEvent, ImageProperty, createDefaultBusinessListing, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model'; @@ -47,9 +48,25 @@ import { TOOLBAR_OPTIONS } from '../../utils/defaults'; ValidatedTextareaComponent, ValidatedLocationComponent, ], - providers: [], + providers: [ + provideQuillConfig({ + modules: { + syntax: true, + toolbar: [ + ['bold', 'italic', 'underline'], + [{ header: [1, 2, 3, false] }], + [{ list: 'ordered' }, { list: 'bullet' }], + [{ color: [] }], + ['clean'], + ], + }, + }) as any, + ], templateUrl: './edit-business-listing.component.html', - styleUrl: './edit-business-listing.component.scss', + styleUrls: [ + './edit-business-listing.component.scss', + '../../../../../node_modules/quill/dist/quill.snow.css' + ], }) export class EditBusinessListingComponent { listingsCategory = 'business'; @@ -64,7 +81,7 @@ export class EditBusinessListingComponent { config = { aspectRatio: 16 / 9 }; editorModules = TOOLBAR_OPTIONS; draggedImage: ImageProperty; - faTrash = faTrash; + faTrash = APP_ICONS.faTrash; data: CommercialPropertyListing; typesOfBusiness = []; quillModules = { diff --git a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html index 3c8ddf4..5ed429b 100644 --- a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html +++ b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.html @@ -58,7 +58,7 @@ (click)="uploadPropertyPicture()" class="flex items-center justify-center px-4 py-2 border border-gray-300 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-50 bg-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" > - + Upload diff --git a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts index a897f35..86105dc 100644 --- a/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts +++ b/bizmatch/src/app/pages/subscription/edit-commercial-property-listing/edit-commercial-property-listing.component.ts @@ -7,11 +7,11 @@ import { map2User, routeListingWithState } from '../../../utils/utils'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { ViewportRuler } from '@angular/cdk/scrolling'; -import { faTrash } from '@fortawesome/free-solid-svg-icons'; +import { APP_ICONS } from '../../../utils/fontawesome-icons'; import { NgSelectModule } from '@ng-select/ng-select'; import { NgxCurrencyDirective } from 'ngx-currency'; import { ImageCropperComponent } from 'ngx-image-cropper'; -import { QuillModule } from 'ngx-quill'; +import { QuillModule, provideQuillConfig } from 'ngx-quill'; import { BusinessListing, CommercialPropertyListing, User } from '../../../../../../bizmatch-server/src/models/db.model'; import { AutoCompleteCompleteEvent, ImageProperty, UploadParams, createDefaultCommercialPropertyListing, emailToDirName } from '../../../../../../bizmatch-server/src/models/main.model'; @@ -53,9 +53,25 @@ import { TOOLBAR_OPTIONS } from '../../utils/defaults'; ValidatedLocationComponent, ImageCropAndUploadComponent, ], - providers: [], + providers: [ + provideQuillConfig({ + modules: { + syntax: true, + toolbar: [ + ['bold', 'italic', 'underline'], + [{ header: [1, 2, 3, false] }], + [{ list: 'ordered' }, { list: 'bullet' }], + [{ color: [] }], + ['clean'], + ], + }, + }) as any, + ], templateUrl: './edit-commercial-property-listing.component.html', - styleUrl: './edit-commercial-property-listing.component.scss', + styleUrls: [ + './edit-commercial-property-listing.component.scss', + '../../../../../node_modules/quill/dist/quill.snow.css' + ], }) export class EditCommercialPropertyListingComponent { @ViewChild('fileInput') fileInput!: ElementRef; @@ -91,7 +107,7 @@ export class EditCommercialPropertyListingComponent { editorModules = TOOLBAR_OPTIONS; draggedImage: ImageProperty; - faTrash = faTrash; + faTrash = APP_ICONS.faTrash; suggestions: string[] | undefined; data: BusinessListing; userId: string; diff --git a/bizmatch/src/app/utils/fontawesome-icons.ts b/bizmatch/src/app/utils/fontawesome-icons.ts new file mode 100644 index 0000000..6c4c2ea --- /dev/null +++ b/bizmatch/src/app/utils/fontawesome-icons.ts @@ -0,0 +1,19 @@ +import { + faArrowRight, + faEnvelope, + faLock, + faTimes, + faTrash, + faUserGear, + faUserPlus +} from '@fortawesome/free-solid-svg-icons'; + +export const APP_ICONS = { + faArrowRight, + faEnvelope, + faLock, + faTimes, + faTrash, + faUserGear, + faUserPlus, +}; diff --git a/bizmatch/src/app/utils/logger.ts b/bizmatch/src/app/utils/logger.ts new file mode 100644 index 0000000..f6b2ccd --- /dev/null +++ b/bizmatch/src/app/utils/logger.ts @@ -0,0 +1,12 @@ +import { environment } from '../../environments/environment'; + +// Development: use browser-bunyan for rich logging +// Production: use lightweight console wrapper to avoid loading 50KB+ library +export const createLogger = environment.production + ? (name: string) => ({ + info: (...args: any[]) => console.log(`[${name}]`, ...args), + warn: (...args: any[]) => console.warn(`[${name}]`, ...args), + error: (...args: any[]) => console.error(`[${name}]`, ...args), + debug: () => {}, // no-op in production + }) + : require('browser-bunyan').createLogger; diff --git a/bizmatch/src/app/utils/utils.ts b/bizmatch/src/app/utils/utils.ts index 93a4aba..9d71a07 100644 --- a/bizmatch/src/app/utils/utils.ts +++ b/bizmatch/src/app/utils/utils.ts @@ -1,5 +1,5 @@ import { Router } from '@angular/router'; -import { ConsoleFormattedStream, INFO, createLogger as _createLogger, stdSerializers } from 'browser-bunyan'; +import { createLogger as _createLogger } from './logger'; import { jwtDecode } from 'jwt-decode'; import onChange from 'on-change'; import { SortByOptions, User } from '../../../../bizmatch-server/src/models/db.model'; @@ -141,14 +141,8 @@ export function createMailInfo(user?: User): MailInfo { listing: null, }; } -export function createLogger(name: string, level: number = INFO, options: any = {}) { - return _createLogger({ - name, - streams: [{ level, stream: new ConsoleFormattedStream() }], - serializers: stdSerializers, - src: true, - ...options, - }); +export function createLogger(name: string, level?: number, options?: any) { + return _createLogger(name); } export function formatPhoneNumber(phone: string): string { const cleaned = ('' + phone).replace(/\D/g, ''); diff --git a/bizmatch/src/assets/images/1_Version.jpg b/bizmatch/src/assets/images/1_Version.jpg deleted file mode 100644 index 8e3a3e9..0000000 Binary files a/bizmatch/src/assets/images/1_Version.jpg and /dev/null differ diff --git a/bizmatch/src/assets/images/2_1_Version.jpg b/bizmatch/src/assets/images/2_1_Version.jpg deleted file mode 100644 index c70083d..0000000 Binary files a/bizmatch/src/assets/images/2_1_Version.jpg and /dev/null differ diff --git a/bizmatch/src/assets/images/2_Version.jpg b/bizmatch/src/assets/images/2_Version.jpg deleted file mode 100644 index 08605bc..0000000 Binary files a/bizmatch/src/assets/images/2_Version.jpg and /dev/null differ diff --git a/bizmatch/src/assets/images/corpusChristiSkyline.jpg b/bizmatch/src/assets/images/corpusChristiSkyline.jpg deleted file mode 100644 index 5aac1b2..0000000 Binary files a/bizmatch/src/assets/images/corpusChristiSkyline.jpg and /dev/null differ diff --git a/bizmatch/src/assets/images/index-bg copy.webp b/bizmatch/src/assets/images/index-bg copy.webp deleted file mode 100644 index 54d8c6d..0000000 Binary files a/bizmatch/src/assets/images/index-bg copy.webp and /dev/null differ diff --git a/bizmatch/src/assets/images/index-bg.jpg b/bizmatch/src/assets/images/index-bg.jpg deleted file mode 100644 index 85f8e8b..0000000 Binary files a/bizmatch/src/assets/images/index-bg.jpg and /dev/null differ diff --git a/bizmatch/src/assets/images/person_placeholder copy.jpg b/bizmatch/src/assets/images/person_placeholder copy.jpg deleted file mode 100644 index 5e2b51e..0000000 Binary files a/bizmatch/src/assets/images/person_placeholder copy.jpg and /dev/null differ diff --git a/bizmatch/src/build.ts b/bizmatch/src/build.ts index 70d5f75..4c5c8fc 100644 --- a/bizmatch/src/build.ts +++ b/bizmatch/src/build.ts @@ -1,6 +1,6 @@ // Build information, automatically generated by `the_build_script` :zwinkern: const build = { - timestamp: "GER: 04.02.2026 15:43 | TX: 02/04/2026 8:43 AM" + timestamp: "GER: 04.02.2026 21:20 | TX: 02/04/2026 2:20 PM" }; export default build; \ No newline at end of file diff --git a/bizmatch/src/styles.scss b/bizmatch/src/styles.scss index 129acf5..11f74a6 100644 --- a/bizmatch/src/styles.scss +++ b/bizmatch/src/styles.scss @@ -7,7 +7,6 @@ // External CSS imports - these URL imports don't trigger deprecation warnings // Using css2 API with specific weights for better performance @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap'); -@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css'); // Local CSS files loaded as CSS (not SCSS) to avoid @import deprecation // Note: These are loaded via angular.json styles array is the preferred approach, @@ -122,7 +121,7 @@ p-menubarsub ul { input::placeholder, textarea::placeholder { - color: #999 !important; + color: #757575 !important; /* 4.54:1 contrast - WCAG AA compliant */ } /* Fix für Marker-Icons in Leaflet */ diff --git a/bizmatch/tsconfig.app.json b/bizmatch/tsconfig.app.json index 7dc7284..f2161bd 100644 --- a/bizmatch/tsconfig.app.json +++ b/bizmatch/tsconfig.app.json @@ -8,9 +8,7 @@ ] }, "files": [ - "src/main.ts", - "src/main.server.ts", - "server.ts" + "src/main.ts" ], "include": [ "src/**/*.d.ts"