diff --git a/client/config.xml b/client/config.xml index 2162e2eac7..4befc0fc18 100644 --- a/client/config.xml +++ b/client/config.xml @@ -23,7 +23,7 @@ - + diff --git a/client/src/cordova/android/OutlineAndroidLib/outline/src/main/java/org/outline/vpn/VpnTunnelService.java b/client/src/cordova/android/OutlineAndroidLib/outline/src/main/java/org/outline/vpn/VpnTunnelService.java index 8a2f6e1016..732db1efdf 100644 --- a/client/src/cordova/android/OutlineAndroidLib/outline/src/main/java/org/outline/vpn/VpnTunnelService.java +++ b/client/src/cordova/android/OutlineAndroidLib/outline/src/main/java/org/outline/vpn/VpnTunnelService.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; @@ -379,6 +380,8 @@ private void broadcastVpnConnectivityChange(TunnelStatus status) { } Intent statusChange = new Intent(STATUS_BROADCAST_KEY); statusChange.addCategory(getPackageName()); + // We must explicitly set the package for security reasons: https://developer.android.com/about/versions/14/behavior-changes-14#security + statusChange.setPackage(this.getPackageName()); statusChange.putExtra(MessageData.PAYLOAD.value, status.value); statusChange.putExtra(MessageData.TUNNEL_ID.value, tunnelConfig.id); sendBroadcast(statusChange); @@ -448,7 +451,9 @@ private void startForegroundWithNotification(final String serverName) { notificationBuilder = getNotificationBuilder(serverName); } notificationBuilder.setContentText(getStringResource("connected_server_state")); - startForeground(NOTIFICATION_SERVICE_ID, notificationBuilder.build()); + + // We must specify the service type for security reasons: https://developer.android.com/about/versions/14/changes/fgs-types-required + startForeground(NOTIFICATION_SERVICE_ID, notificationBuilder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE); } catch (Exception e) { LOG.warning("Unable to display persistent notification"); } diff --git a/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.pbxproj b/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.pbxproj index 650e822325..512bebb378 100755 --- a/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.pbxproj +++ b/client/src/cordova/apple/xcode/ios/Outline.xcodeproj/project.pbxproj @@ -21,7 +21,7 @@ 5F7F90AE0E924FD7B065C415 /* CDVStatusBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 0394302BA6114B2AB648D4FF /* CDVStatusBar.m */; }; 65A9AC9C2BEC091700C5899F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 65A9AC9B2BEC091700C5899F /* PrivacyInfo.xcprivacy */; }; 6AFF5BF91D6E424B00AB3073 /* CDVLaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6AFF5BF81D6E424B00AB3073 /* CDVLaunchScreen.storyboard */; }; - A246B7E52B07AADD00ECACD5 /* AppKitIntegration.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A246B7DD2B07AACF00ECACD5 /* AppKitIntegration.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + A246B7E52B07AADD00ECACD5 /* AppKitIntegration.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A246B7DD2B07AACF00ECACD5 /* AppKitIntegration.framework */; platformFilter = maccatalyst; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; A25FB7DC2B0D4420009B6B5F /* AppKitIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = A272490D2B0D20530018A598 /* AppKitIntegration.h */; settings = {ATTRIBUTES = (Public, ); }; }; A271D42D2A708240009981B2 /* AppDelegate+Outline.m in Sources */ = {isa = PBXBuildFile; fileRef = A271D42C2A708240009981B2 /* AppDelegate+Outline.m */; }; A271D4342A70829D009981B2 /* OutlineAppleLib in Frameworks */ = {isa = PBXBuildFile; productRef = A271D4332A70829D009981B2 /* OutlineAppleLib */; }; @@ -692,6 +692,7 @@ }; A246B7E72B07AADD00ECACD5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; + platformFilter = maccatalyst; target = A246B7DC2B07AACF00ECACD5 /* AppKitIntegration */; targetProxy = A246B7E62B07AADD00ECACD5 /* PBXContainerItemProxy */; }; diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-1024.png deleted file mode 100644 index 1b2c3fffb5..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-1024.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-128.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-128.png deleted file mode 100644 index 8404b66d9f..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-128.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-16.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-16.png deleted file mode 100644 index 0babf3728f..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-16.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-256.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-256.png deleted file mode 100644 index b272c20ce9..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-256.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-32.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-32.png deleted file mode 100644 index c80d6bc1ca..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-32.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-512.png b/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-512.png deleted file mode 100644 index 6eff93b62c..0000000000 Binary files a/client/src/cordova/apple/xcode/ios/Outline/Assets.xcassets/AppIcon.appiconset/icon-512.png and /dev/null differ diff --git a/client/src/cordova/apple/xcode/macos/Outline/config.xml b/client/src/cordova/apple/xcode/macos/Outline/config.xml index d8819571b9..d24f8d1aa4 100755 --- a/client/src/cordova/apple/xcode/macos/Outline/config.xml +++ b/client/src/cordova/apple/xcode/macos/Outline/config.xml @@ -51,8 +51,8 @@ - - + + diff --git a/client/src/cordova/build.action.mjs b/client/src/cordova/build.action.mjs index 863ea3be41..13ddb63b58 100644 --- a/client/src/cordova/build.action.mjs +++ b/client/src/cordova/build.action.mjs @@ -38,7 +38,9 @@ export async function main(...parameters) { await runAction('client/src/cordova/setup', ...parameters); if (verbose) { - cordova.on('verbose', message => console.debug(`[cordova:verbose] ${message}`)); + cordova.on('verbose', message => + console.debug(`[cordova:verbose] ${message}`) + ); } // this is so cordova doesn't complain about not being in a cordova project @@ -49,10 +51,17 @@ export async function main(...parameters) { return androidDebug(verbose); case 'android' + 'release': if (!process.env.JAVA_HOME) { - throw new ReferenceError('JAVA_HOME must be defined in the environment to build an Android Release!'); + throw new ReferenceError( + 'JAVA_HOME must be defined in the environment to build an Android Release!' + ); } - if (!(process.env.ANDROID_KEY_STORE_PASSWORD && process.env.ANDROID_KEY_STORE_CONTENTS)) { + if ( + !( + process.env.ANDROID_KEY_STORE_PASSWORD && + process.env.ANDROID_KEY_STORE_CONTENTS + ) + ) { throw new ReferenceError( "Both 'ANDROID_KEY_STORE_PASSWORD' and 'ANDROID_KEY_STORE_CONTENTS' must be defined in the environment to build an Android Release!" ); @@ -94,7 +103,14 @@ function getXcodeBuildArgs(platform) { } return [ '-workspace', - path.join(getRootDir(), 'client', 'src', 'cordova', 'apple', workspaceFilename), + path.join( + getRootDir(), + 'client', + 'src', + 'cordova', + 'apple', + workspaceFilename + ), '-scheme', 'Outline', '-destination', @@ -103,7 +119,9 @@ function getXcodeBuildArgs(platform) { } async function appleDebug(platform) { - console.warn(`WARNING: building "${platform}" in [DEBUG] mode. Do not publish this build!!`); + console.warn( + `WARNING: building "${platform}" in [DEBUG] mode. Do not publish this build!!` + ); return spawnStream( 'xcodebuild', @@ -118,11 +136,20 @@ async function appleDebug(platform) { } async function appleRelease(platform) { - return spawnStream('xcodebuild', 'clean', ...getXcodeBuildArgs(platform), 'archive', '-configuration', 'Release'); + return spawnStream( + 'xcodebuild', + 'clean', + ...getXcodeBuildArgs(platform), + 'archive', + '-configuration', + 'Release' + ); } async function androidDebug(verbose) { - console.warn(`WARNING: building "android" in [DEBUG] mode. Do not publish this build!!`); + console.warn( + 'WARNING: building "android" in [DEBUG] mode. Do not publish this build!!' + ); return cordova.compile({ verbose, @@ -142,7 +169,12 @@ const JAVA_BUNDLETOOL_VERSION = '1.8.2'; const JAVA_BUNDLETOOL_RESOURCE_URL = `https://github.com/google/bundletool/releases/download/1.8.2/bundletool-all-${JAVA_BUNDLETOOL_VERSION}.jar`; async function androidRelease(ksPassword, ksContents, javaPath, verbose) { - const androidBuildPath = path.resolve(getRootDir(), 'platforms', 'android'); + const androidBuildPath = path.resolve( + getRootDir(), + 'client', + 'platforms', + 'android' + ); const keystorePath = path.resolve(androidBuildPath, 'keystore.p12'); await fs.writeFile(keystorePath, Buffer.from(ksContents, 'base64')); @@ -176,7 +208,15 @@ async function androidRelease(ksPassword, ksContents, javaPath, verbose) { '-jar', bundletoolPath, 'build-apks', - `--bundle=${path.resolve(androidBuildPath, 'app', 'build', 'outputs', 'bundle', 'release', 'app-release.aab')}`, + `--bundle=${path.resolve( + androidBuildPath, + 'app', + 'build', + 'outputs', + 'bundle', + 'release', + 'app-release.aab' + )}`, `--output=${outputPath}`, '--mode=universal', `--ks=${keystorePath}`, diff --git a/client/src/cordova/plugin/plugin.xml b/client/src/cordova/plugin/plugin.xml index 9e0e871804..2dac7b6fc9 100644 --- a/client/src/cordova/plugin/plugin.xml +++ b/client/src/cordova/plugin/plugin.xml @@ -38,11 +38,13 @@ +