@@ -765,33 +765,46 @@ public async Task<IActionResult> PushNotifications(PushNotificationsSettingsMode
765765
766766 private void SavePushNotificationsToFile ( PushNotificationsSettingsModel model , IConfiguration configuration , IWebHostEnvironment webHostEnvironment )
767767 {
768- //edit js file needed by firebase
769- var filename = "firebase-messaging-sw.js" ;
770- var filePath = Path . Combine ( webHostEnvironment . WebRootPath , configuration [ CommonPath . DirectoryParam ] ?? "" , filename ) ;
771- if ( System . IO . File . Exists ( filePath ) )
772- {
773- var lines = System . IO . File . ReadAllLines ( filePath ) ;
774- var i = 0 ;
775- foreach ( var line in lines )
776- {
777- if ( line . Contains ( "apiKey" ) ) lines [ i ] = "apiKey: \" " + model . PushApiKey + "\" ," ;
778- if ( line . Contains ( "authDomain" ) ) lines [ i ] = "authDomain: \" " + model . AuthDomain + "\" ," ;
779- if ( line . Contains ( "databaseURL" ) ) lines [ i ] = "databaseURL: \" " + model . DatabaseUrl + "\" ," ;
780- if ( line . Contains ( "projectId" ) ) lines [ i ] = "projectId: \" " + model . ProjectId + "\" ," ;
781- if ( line . Contains ( "storageBucket" ) ) lines [ i ] = "storageBucket: \" " + model . StorageBucket + "\" ," ;
782- if ( line . Contains ( "messagingSenderId" ) ) lines [ i ] = "messagingSenderId: \" " + model . SenderId + "\" ," ;
783- if ( line . Contains ( "appId" ) ) lines [ i ] = "appId: \" " + model . AppId + "\" ," ;
784- i ++ ;
785- }
768+ var fullPath = GetSafeFilePath ( configuration , webHostEnvironment , "firebase-messaging-sw.js" ) ;
786769
787- System . IO . File . WriteAllLines ( filePath , lines ) ;
770+ if ( System . IO . File . Exists ( fullPath ) )
771+ {
772+ var lines = System . IO . File . ReadAllLines ( fullPath ) ;
773+ lines = UpdateFileLines ( lines , model ) ;
774+ System . IO . File . WriteAllLines ( fullPath , lines ) ;
788775 }
789776 else
777+ throw new ArgumentNullException ( $ "{ fullPath } not exist") ;
778+ }
779+
780+ private string GetSafeFilePath ( IConfiguration configuration , IWebHostEnvironment webHostEnvironment , string filename )
781+ {
782+ var directoryParam = configuration [ CommonPath . DirectoryParam ] ?? "" ;
783+ var safeDirectoryName = Path . GetFileName ( directoryParam ) ;
784+ var combinedPath = Path . Combine ( webHostEnvironment . WebRootPath , safeDirectoryName , filename ) ;
785+ var fullPath = Path . GetFullPath ( combinedPath , webHostEnvironment . WebRootPath ) ;
786+
787+ if ( ! fullPath . StartsWith ( webHostEnvironment . WebRootPath , StringComparison . OrdinalIgnoreCase ) )
788+ throw new ArgumentException ( "Invalid path parameter - attempt to go outside allowed directory." ) ;
789+
790+ return fullPath ;
791+ }
792+
793+ private string [ ] UpdateFileLines ( string [ ] lines , PushNotificationsSettingsModel model )
794+ {
795+ for ( var i = 0 ; i < lines . Length ; i ++ )
790796 {
791- throw new ArgumentNullException ( $ "{ filePath } not exist") ;
797+ if ( lines [ i ] . Contains ( "apiKey" ) ) lines [ i ] = $ "apiKey: \" { model . PushApiKey } \" ,";
798+ if ( lines [ i ] . Contains ( "authDomain" ) ) lines [ i ] = $ "authDomain: \" { model . AuthDomain } \" ,";
799+ if ( lines [ i ] . Contains ( "databaseURL" ) ) lines [ i ] = $ "databaseURL: \" { model . DatabaseUrl } \" ,";
800+ if ( lines [ i ] . Contains ( "projectId" ) ) lines [ i ] = $ "projectId: \" { model . ProjectId } \" ,";
801+ if ( lines [ i ] . Contains ( "storageBucket" ) ) lines [ i ] = $ "storageBucket: \" { model . StorageBucket } \" ,";
802+ if ( lines [ i ] . Contains ( "messagingSenderId" ) ) lines [ i ] = $ "messagingSenderId: \" { model . SenderId } \" ,";
803+ if ( lines [ i ] . Contains ( "appId" ) ) lines [ i ] = $ "appId: \" { model . AppId } \" ,";
792804 }
805+ return lines ;
793806 }
794-
807+
795808 public IActionResult AdminSearch ( )
796809 {
797810 var settings = settingService . LoadSetting < AdminSearchSettings > ( ) ;
0 commit comments