diff --git a/src/app/shared/apps-flyer/apps-flyer.service.ts b/src/app/shared/apps-flyer/apps-flyer.service.ts index 8b5192493..15d67931d 100644 --- a/src/app/shared/apps-flyer/apps-flyer.service.ts +++ b/src/app/shared/apps-flyer/apps-flyer.service.ts @@ -3,6 +3,7 @@ import { AdvertisingId } from '@capacitor-community/advertising-id'; import { Capacitor } from '@capacitor/core'; import { Platform } from '@ionic/angular'; import { AFEvent, AFInit, AppsFlyer } from 'appsflyer-capacitor-plugin'; +import { environment } from '../../../environments/environment'; import { APPS_FLYER_DEV_KEY } from '../dia-backend/secret'; import { CCamCustomEventType } from './apps-flyer-enums'; @@ -12,7 +13,7 @@ import { CCamCustomEventType } from './apps-flyer-enums'; export class AppsFlyerService { private readonly INIT_TIMEOUT_MS = 2000; private readonly afConfig: AFInit = { - appID: '1536388009', // AppStore Application ID. For iOS only. + appID: environment.appsFlyerAppId, // AppStore Application ID. For iOS only. devKey: APPS_FLYER_DEV_KEY, isDebug: false, waitForATTUserAuthorization: 15, // for iOS 14 and higher diff --git a/src/app/shared/media/media-viewer/media-viewer.page.ts b/src/app/shared/media/media-viewer/media-viewer.page.ts index 9fd330f3e..5d4872bf3 100644 --- a/src/app/shared/media/media-viewer/media-viewer.page.ts +++ b/src/app/shared/media/media-viewer/media-viewer.page.ts @@ -1,10 +1,12 @@ import { Component } from '@angular/core'; -import { DomSanitizer } from '@angular/platform-browser'; +import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { ActivatedRoute } from '@angular/router'; import { NavController } from '@ionic/angular'; -import { distinctUntilChanged, map } from 'rxjs/operators'; +import { distinctUntilChanged, filter, map } from 'rxjs/operators'; import { isNonNullable } from '../../../utils/rx-operators/rx-operators'; +const ALLOWED_URL_SCHEMES = ['blob:', 'https:', 'capacitor:']; + @Component({ selector: 'app-media-viewer', templateUrl: './media-viewer.page.html', @@ -15,7 +17,16 @@ export class MediaViewerPage { map(params => params.get('src')), isNonNullable(), distinctUntilChanged(), - map(src => this.sanitizer.bypassSecurityTrustUrl(src)) + map((src): SafeUrl | null => { + if (!ALLOWED_URL_SCHEMES.some(scheme => src.startsWith(scheme))) { + // eslint-disable-next-line no-console + console.error(`Blocked media URL with disallowed scheme: ${src}`); + this.navController.back(); + return null; + } + return this.sanitizer.bypassSecurityTrustUrl(src); + }), + filter((src): src is SafeUrl => src !== null) ); private readonly mimeType$ = this.route.paramMap.pipe( diff --git a/src/app/shared/social-auth/social-auth.service.ts b/src/app/shared/social-auth/social-auth.service.ts index 1a506ff63..b5b40db57 100644 --- a/src/app/shared/social-auth/social-auth.service.ts +++ b/src/app/shared/social-auth/social-auth.service.ts @@ -20,7 +20,7 @@ export interface SocialUser { }) export class SocialAuthService { private initialized = false; - private initializing = false; + private initializationPromise: Promise | undefined; // No dependencies needed for this service constructor() { @@ -28,36 +28,33 @@ export class SocialAuthService { } private async initSocialAuth(): Promise { - // Prevent multiple initializations - if (this.initialized || this.initializing) { - return; + if (this.initialized) { + return Promise.resolve(); } - this.initializing = true; - - try { - // Initialize the SocialLogin plugin with Google authentication credentials - // For iOS, we use a specific iOS client ID - // For Android and Web, we use the web client ID - await SocialLogin.initialize({ + if (!this.initializationPromise) { + this.initializationPromise = SocialLogin.initialize({ google: { iOSClientId: GOOGLE_IOS_CLIENT_ID, webClientId: GOOGLE_WEB_CLIENT_ID, }, - }); - this.initialized = true; - } finally { - this.initializing = false; + }) + .then(() => { + this.initialized = true; + }) + .catch((err: unknown) => { + this.initializationPromise = undefined; + throw err; + }); } + + return this.initializationPromise; } /** * Method to ensure the service is initialized */ ensureInitialized$(): Observable { - if (this.initialized) { - return from(Promise.resolve()); - } return from(this.initSocialAuth()); } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index c9669790b..48a8d8b0a 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,4 @@ export const environment = { production: true, + appsFlyerAppId: '1536388009', }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 31cb7855f..a030efbd6 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -4,6 +4,7 @@ export const environment = { production: false, + appsFlyerAppId: '1536388009', }; /*