@ -56,6 +56,7 @@ export class CapacitorPlatformService implements PlatformService {
private permissionRequestLock : Promise < void > | null = null ;
private permissionRequestLock : Promise < void > | null = null ;
private permissionGranted : boolean = false ;
private permissionGranted : boolean = false ;
private permissionChecked : boolean = false ;
private permissionChecked : boolean = false ;
private lastPermissionCheck : number = 0 ;
constructor ( ) {
constructor ( ) {
this . sqlite = new SQLiteConnection ( CapacitorSQLite ) ;
this . sqlite = new SQLiteConnection ( CapacitorSQLite ) ;
@ -267,34 +268,22 @@ export class CapacitorPlatformService implements PlatformService {
* /
* /
private async checkStoragePermissions ( ) : Promise < void > {
private async checkStoragePermissions ( ) : Promise < void > {
try {
try {
const logData = {
// Skip permission check on iOS - Documents directory is accessible by default
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
timestamp : new Date ( ) . toISOString ( ) ,
} ;
logger . log (
"Checking storage permissions" ,
JSON . stringify ( logData , null , 2 ) ,
) ;
if ( this . getCapabilities ( ) . isIOS ) {
if ( this . getCapabilities ( ) . isIOS ) {
// iOS uses different permission model - Documents directory is accessible
logger . log ( "iOS platform - Documents directory is accessible by default" ) ;
return ;
return ;
}
}
// Check if we already have permissions
// Check if we already have recent permission status (cache for 30 seconds)
if ( this . permissionChecked && this . permissionGranted ) {
const now = Date . now ( ) ;
logger . log ( "External storage permissions already granted" , {
const cacheExpiry = 30000 ; // 30 seconds
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
if ( this . permissionChecked && this . permissionGranted &&
return ;
( now - this . lastPermissionCheck ) < cacheExpiry ) {
return ; // Use cached permission status
}
}
// If a permission request is already in progress, wait for it
// If a permission request is already in progress, wait for it
if ( this . permissionRequestLock ) {
if ( this . permissionRequestLock ) {
logger . log ( "Permission request already in progress, waiting..." , {
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
await this . permissionRequestLock ;
await this . permissionRequestLock ;
return ;
return ;
}
}
@ -306,12 +295,11 @@ export class CapacitorPlatformService implements PlatformService {
await this . permissionRequestLock ;
await this . permissionRequestLock ;
this . permissionGranted = true ;
this . permissionGranted = true ;
this . permissionChecked = true ;
this . permissionChecked = true ;
logger . log ( "Storage permissions granted successfully" , {
this . lastPermissionCheck = now ;
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
} catch ( error ) {
} catch ( error ) {
this . permissionGranted = false ;
this . permissionGranted = false ;
this . permissionChecked = true ;
this . permissionChecked = true ;
this . lastPermissionCheck = now ;
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
logger . warn ( "Storage permissions denied, continuing with limited functionality" , {
logger . warn ( "Storage permissions denied, continuing with limited functionality" , {
error : errorMessage ,
error : errorMessage ,
@ -343,19 +331,14 @@ export class CapacitorPlatformService implements PlatformService {
directory : Directory.ExternalStorage ,
directory : Directory.ExternalStorage ,
} ) ;
} ) ;
logger . log ( "External storage permissions already granted" , {
// Permissions are already granted
timestamp : new Date ( ) . toISOString ( ) ,
return ;
} ) ;
} catch ( error ) {
} catch ( error ) {
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
// Check if this is a permission denial
// Check if this is a permission denial
if ( errorMessage . includes ( "user denied permission" ) ||
if ( errorMessage . includes ( "user denied permission" ) ||
errorMessage . includes ( "permission request" ) ) {
errorMessage . includes ( "permission request" ) ) {
logger . warn ( "User denied storage permission" , {
error : errorMessage ,
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
throw new Error ( "Storage permission denied by user" ) ;
throw new Error ( "Storage permission denied by user" ) ;
}
}
@ -1824,12 +1807,15 @@ export class CapacitorPlatformService implements PlatformService {
// Use enhanced file discovery to find files regardless of where users saved them
// Use enhanced file discovery to find files regardless of where users saved them
const allFiles = await this . listUserAccessibleFilesEnhanced ( ) ;
const allFiles = await this . listUserAccessibleFilesEnhanced ( ) ;
logger . log ( "[CapacitorPlatformService] All user accessible files found (enhanced):" , {
// Only log if files are found or if this is a debug session
total : allFiles.length ,
if ( allFiles . length > 0 ) {
files : allFiles.map ( f = > ( { name : f.name , path : f.path , size : f.size } ) ) ,
logger . log ( "[CapacitorPlatformService] All user accessible files found (enhanced):" , {
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
total : allFiles.length ,
timestamp : new Date ( ) . toISOString ( ) ,
files : allFiles.map ( f = > ( { name : f.name , path : f.path , size : f.size } ) ) ,
} ) ;
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
}
// Show ALL JSON files and any files with backup-related keywords
// Show ALL JSON files and any files with backup-related keywords
const backupFiles = allFiles
const backupFiles = allFiles
@ -1837,7 +1823,6 @@ export class CapacitorPlatformService implements PlatformService {
const name = file . name . toLowerCase ( ) ;
const name = file . name . toLowerCase ( ) ;
// Exclude directory-access notification files
// Exclude directory-access notification files
if ( name . startsWith ( 'timesafari-directory-access-' ) && name . endsWith ( '.txt' ) ) {
if ( name . startsWith ( 'timesafari-directory-access-' ) && name . endsWith ( '.txt' ) ) {
logger . log ( "[CapacitorPlatformService] Excluding directory access file:" , file . name ) ;
return false ;
return false ;
}
}
@ -1852,7 +1837,8 @@ export class CapacitorPlatformService implements PlatformService {
const isBackupFile = isJson || hasTimeSafari || hasBackup || hasContacts || hasSeed || hasExport || hasData ;
const isBackupFile = isJson || hasTimeSafari || hasBackup || hasContacts || hasSeed || hasExport || hasData ;
if ( ! isBackupFile ) {
// Only log exclusions in debug mode or if no backup files are found
if ( ! isBackupFile && allFiles . length > 0 ) {
logger . log ( "[CapacitorPlatformService] Excluding file (no backup keywords):" , {
logger . log ( "[CapacitorPlatformService] Excluding file (no backup keywords):" , {
name : file.name ,
name : file.name ,
path : file.path ,
path : file.path ,
@ -1888,16 +1874,19 @@ export class CapacitorPlatformService implements PlatformService {
} ;
} ;
} ) ;
} ) ;
logger . log ( "[CapacitorPlatformService] Found backup files (enhanced discovery):" , {
// Only log if backup files are found
total : backupFiles.length ,
if ( backupFiles . length > 0 ) {
files : backupFiles.map ( f = > ( {
logger . log ( "[CapacitorPlatformService] Found backup files (enhanced discovery):" , {
name : f.name ,
total : backupFiles.length ,
type : f . type ,
files : backupFiles.map ( f = > ( {
path : f.path
name : f.name ,
} ) ) ,
type : f . type ,
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
path : f.path
timestamp : new Date ( ) . toISOString ( ) ,
} ) ) ,
} ) ;
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
}
// If no backup files found, log helpful information for debugging
// If no backup files found, log helpful information for debugging
if ( backupFiles . length === 0 && allFiles . length > 0 ) {
if ( backupFiles . length === 0 && allFiles . length > 0 ) {
@ -2327,11 +2316,14 @@ export class CapacitorPlatformService implements PlatformService {
allFiles . push ( . . . dataFiles ) ;
allFiles . push ( . . . dataFiles ) ;
logger . log ( "[CapacitorPlatformService] App data directory files found:" , {
// Only log if files are found or if this is the first discovery
fileCount : dataFiles.length ,
if ( dataFiles . length > 0 ) {
files : dataFiles.map ( f = > ( { name : f.name , size : f.size } ) ) ,
logger . log ( "[CapacitorPlatformService] App data directory files found:" , {
timestamp : new Date ( ) . toISOString ( ) ,
fileCount : dataFiles.length ,
} ) ;
files : dataFiles.map ( f = > ( { name : f.name , size : f.size } ) ) ,
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
}
} catch ( error ) {
} catch ( error ) {
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
const errorMessage = error instanceof Error ? error.message : String ( error ) ;
logger . warn ( "[CapacitorPlatformService] Could not read app data directory:" , {
logger . warn ( "[CapacitorPlatformService] Could not read app data directory:" , {
@ -2340,13 +2332,16 @@ export class CapacitorPlatformService implements PlatformService {
} ) ;
} ) ;
}
}
logger . log ( "[CapacitorPlatformService] Enhanced file discovery results:" , {
// Only log summary if files are found or if this is a debug session
totalFiles : allFiles.length ,
if ( allFiles . length > 0 ) {
hasPermissions ,
logger . log ( "[CapacitorPlatformService] Enhanced file discovery results:" , {
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
totalFiles : allFiles.length ,
files : allFiles.map ( f = > ( { name : f.name , path : f.path , size : f.size } ) ) ,
hasPermissions ,
timestamp : new Date ( ) . toISOString ( ) ,
platform : this.getCapabilities ( ) . isIOS ? "iOS" : "Android" ,
} ) ;
files : allFiles.map ( f = > ( { name : f.name , path : f.path , size : f.size } ) ) ,
timestamp : new Date ( ) . toISOString ( ) ,
} ) ;
}
return allFiles ;
return allFiles ;
} catch ( error ) {
} catch ( error ) {