From 5ac1619938828d5528bd735c2e2d70332e54e295 Mon Sep 17 00:00:00 2001 From: Daniel LaCosse <3759828+daniellacosse@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:14:11 -0500 Subject: [PATCH] rename and move everything --- x/examples/outline-pwa/README.md | 345 -------------- .../.gitignore | 0 .../LICENSE | 0 x/examples/outline-web-wrapper/README.md | 425 ++++++++++++++++++ .../android/.gitignore | 0 .../android/app/.gitignore | 0 .../android/app/build.gradle | 0 .../android/app/capacitor.build.gradle | 0 .../android/app/proguard-rules.pro | 0 .../myapp/ExampleInstrumentedTest.java | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../java/org/getoutline/pwa/MainActivity.kt | 0 .../main/res/drawable-land-hdpi/splash.png | Bin .../main/res/drawable-land-mdpi/splash.png | Bin .../main/res/drawable-land-xhdpi/splash.png | Bin .../main/res/drawable-land-xxhdpi/splash.png | Bin .../main/res/drawable-land-xxxhdpi/splash.png | Bin .../main/res/drawable-port-hdpi/splash.png | Bin .../main/res/drawable-port-mdpi/splash.png | Bin .../main/res/drawable-port-xhdpi/splash.png | Bin .../main/res/drawable-port-xxhdpi/splash.png | Bin .../main/res/drawable-port-xxxhdpi/splash.png | Bin .../drawable-v24/ic_launcher_foreground.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 .../app/src/main/res/drawable/splash.png | Bin .../app/src/main/res/layout/activity_main.xml | 0 .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../mipmap-hdpi/ic_launcher_foreground.png | Bin .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../mipmap-mdpi/ic_launcher_foreground.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../mipmap-xhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../res/values/ic_launcher_background.xml | 0 .../app/src/main/res/values/strings.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../app/src/main/res/xml/file_paths.xml | 0 .../getcapacitor/myapp/ExampleUnitTest.java | 0 .../android/build.gradle | 0 .../android/capacitor.settings.gradle | 0 .../android/gradle.properties | 0 .../android/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../android/gradlew | 0 .../android/gradlew.bat | 0 .../android/settings.gradle | 0 .../android/variables.gradle | 0 .../capacitor.config.json | 0 .../generated/mobileproxy.aar | Bin .../mobileproxy.xcframework/Info.plist | 0 .../Headers/Mobileproxy.h | 0 .../Headers/Mobileproxy.objc.h | 0 .../Headers/Universe.objc.h | 0 .../Mobileproxy.framework/Headers/ref.h | 0 .../Mobileproxy.framework/Info.plist | 0 .../Mobileproxy.framework/Mobileproxy | Bin .../Modules/module.modulemap | 0 .../Headers/Mobileproxy.h | 0 .../Headers/Mobileproxy.objc.h | 0 .../Headers/Universe.objc.h | 0 .../Mobileproxy.framework/Headers/ref.h | 0 .../Mobileproxy.framework/Info.plist | 0 .../Mobileproxy.framework/Mobileproxy | Bin .../Modules/module.modulemap | 0 .../ios/.gitignore | 0 .../ios/App/App.xcodeproj/project.pbxproj | 0 .../App.xcworkspace/contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../ios/App/App/AppDelegate.swift | 0 .../AppIcon.appiconset/AppIcon-512@2x.png | Bin .../AppIcon.appiconset/Contents.json | 0 .../ios/App/App/Assets.xcassets/Contents.json | 0 .../Splash.imageset/Contents.json | 0 .../Splash.imageset/splash-2732x2732-1.png | Bin .../Splash.imageset/splash-2732x2732-2.png | Bin .../Splash.imageset/splash-2732x2732.png | Bin .../App/Base.lproj/LaunchScreen.storyboard | 0 .../ios/App/App/Base.lproj/Main.storyboard | 0 .../ios/App/App/Info.plist | 0 .../App/App/OutlineBridgeViewController.swift | 0 .../ios/App/Podfile | 0 .../ios/App/Podfile.lock | 0 .../package-lock.json | 0 .../package.json | 0 94 files changed, 425 insertions(+), 345 deletions(-) delete mode 100644 x/examples/outline-pwa/README.md rename x/examples/{outline-pwa => outline-web-wrapper}/.gitignore (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/LICENSE (100%) create mode 100644 x/examples/outline-web-wrapper/README.md rename x/examples/{outline-pwa => outline-web-wrapper}/android/.gitignore (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/.gitignore (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/build.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/capacitor.build.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/proguard-rules.pro (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/AndroidManifest.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-land-hdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-land-mdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-land-xhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-land-xxhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-land-xxxhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-port-hdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-port-mdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-port-xhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-port-xxhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-port-xxxhdpi/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable/ic_launcher_background.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/drawable/splash.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/layout/activity_main.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/values/ic_launcher_background.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/values/strings.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/values/styles.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/main/res/xml/file_paths.xml (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/build.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/capacitor.settings.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/gradle.properties (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/gradle/wrapper/gradle-wrapper.jar (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/gradle/wrapper/gradle-wrapper.properties (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/gradlew (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/gradlew.bat (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/settings.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/android/variables.gradle (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/capacitor.config.json (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.aar (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/Info.plist (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.objc.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Universe.objc.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/ref.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Info.plist (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Mobileproxy (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Modules/module.modulemap (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.objc.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Universe.objc.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/ref.h (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Info.plist (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Mobileproxy (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Modules/module.modulemap (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/.gitignore (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App.xcodeproj/project.pbxproj (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App.xcworkspace/contents.xcworkspacedata (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/AppDelegate.swift (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/Contents.json (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Base.lproj/LaunchScreen.storyboard (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Base.lproj/Main.storyboard (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/Info.plist (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/App/OutlineBridgeViewController.swift (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/Podfile (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/ios/App/Podfile.lock (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/package-lock.json (100%) rename x/examples/{outline-pwa => outline-web-wrapper}/package.json (100%) diff --git a/x/examples/outline-pwa/README.md b/x/examples/outline-pwa/README.md deleted file mode 100644 index 8017f35e..00000000 --- a/x/examples/outline-pwa/README.md +++ /dev/null @@ -1,345 +0,0 @@ -# Building a Censorship-Resistant Android/iOS App with CapacitorJS and the Outline SDK Mobileproxy - -This code lab guides you through creating a censorship-resistant Android/iOS app from scratch that wraps your Progressive Web App (PWA) using CapacitorJS and the Outline SDK Mobileproxy. This setup routes your site's traffic through the Outline proxy, bypassing network restrictions. Note that the source in this folder is representative of what your end product should look like once the code lab is completed. - -**Prerequisites:** - -* A website you want to make censorship resistant. -* Make sure your development environment is set up with the following. **[Please follow CapacitorJS's environment setup guide](https://capacitorjs.com/docs/getting-started/environment-setup)** - * [Node.js](https://nodejs.org/en/), for the Capacitor build system. - * [GoLang](https://go.dev/), to build the Outline Mobile Proxy. - * For Android, [OpenJDK 17](https://stackoverflow.com/a/70649641) and [Android Studio](https://developer.android.com/studio/) - * For iOS, [XCode](https://developer.apple.com/xcode/) and [cocoapods](https://cocoapods.org/) -* [Wireshark](https://www.wireshark.org/), to confirm the app is working - -## Set up the Capacitor Project - -* Follow the CapacitorJS Getting Started guide to initialize a new project: [https://capacitorjs.com/docs/getting-started](https://capacitorjs.com/docs/getting-started) - -> [!NOTE] -> This will create a new directory containing your project. Make sure you run these commands relative to where you want your project to live. - - ```bash - npm init @capacitor/app # follow the instructions - make sure to pick an app ID that's unique! - cd - npm install - ``` - -* Add iOS and Android platforms to your project: - - ```bash - npm install @capacitor/android @capacitor/ios - npx cap add android - npx cap add ios - - mkdir android/app/src/main/assets # sync will fail without this folder - npm run build # this builds the stock web app that the default project ships with - npx cap sync - ``` - -## Confirm that the default apps are able to run - -### iOS - -* Open the iOS project in XCode with `npx cap open ios`. -* Make sure the correct emulator or device is selected and press the ▶️ button. - -### Android - -* Open the Android project in Android Studio with `npx cap open android`. -* Ensure you have an emulator with Android API 35 or later (check `Tools > Device Manager`), then press the ▶️ button. - ---- - -## Configure Capacitor to Load Your PWA - -* **Update `capacitor.config.json`:** - - ```json - { - "appId": "com.yourcompany.yourapp", - "appName": "YourAppName", - "bundledWebRuntime": false, - "server": { - "url": "https://www.your-pwa-url.com" - } - } - ``` - - > [!NOTE] - > Capacitor will silently fail to read your config if the JSON is invalid. Be sure to check `capacitor.config.json` for any hanging commas! - -## Integrate the Outline SDK Mobileproxy Library - -**Build the Mobileproxy library:** - * [Follow the instructions in the Outline SDK repository](https://github.com/Jigsaw-Code/outline-sdk/tree/main/x/mobileproxy#build-the-go-mobile-binaries-with-go-build): - - ```bash - git clone https://github.com/Jigsaw-Code/outline-sdk.git - cd outline-sdk/x - go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind - - PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o "$(pwd)/out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy - PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=android -androidapi=21 -o "$(pwd)/out/mobileproxy.aar" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy - ``` - -### iOS Integration - * Open the XCode project with `npx cap open ios`. - * Add the compiled `mobileproxy.xcframework` static library to your Xcode project: - * Right click on the `Frameworks` folder. - * Select `Add Files to "App"...` - * Select the `mobileproxy.xcframework` folder. - - * Create a new file called `OutlineBridgeViewController.swift`: - * Right click on the `App` folder. - * Select `New File...` - * Select the `Swift File` and click `Next`. - * Enter in the file name. - - * Extend the base Capacitor Bridge View Controller: - ```swift - import UIKit - import Capacitor - - class OutlineBridgeViewController: CAPBridgeViewController { - private let proxyHost: String = "127.0.0.1" - private let proxyPort: String = "8080" - } - ``` - * Override the `webView` method to inject the proxy configuration: - - ```swift - override func webView(with frame: CGRect, configuration: WKWebViewConfiguration) -> WKWebView { - if #available(iOS 17.0, *) { - let endpoint = NWEndpoint.hostPort( - host: NWEndpoint.Host(self.proxyHost), - port: NWEndpoint.Port(self.proxyPort)! - ) - let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint) - - let websiteDataStore = WKWebsiteDataStore.default() - websiteDataStore.proxyConfigurations = [proxyConfig] - - configuration.websiteDataStore = websiteDataStore - } - - return super.webView(with: frame, configuration: configuration) - } - ``` - - * In `AppDelegate.swift`, set the `rootViewController` to your new `OutlineBridgeViewController`: - - ```swift - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - - self.window?.rootViewController = OutlineBridgeViewController() - - return true - } - ``` - - * Import the Mobileproxy framework at the head of the `AppDelegate.swift` file: - - ```swift - import Mobileproxy - ``` - - * Create a `proxy` property on the `AppDelegate`: - - ```swift - var proxy: MobileproxyProxy? - ``` - - * Then set up the dialer and start the proxy in `applicationDidBecomeActive`: - - ```swift - func applicationDidBecomeActive(_ application: UIApplication) { - var dialerError: NSError? - if let dialer = MobileproxyNewSmartStreamDialer( - MobileproxyNewListFromLines("www.your-pwa-url.com"), - "{\"dns\":[{\"https\":{\"name\":\"9.9.9.9\"}}],\"tls\":[\"\",\"split:1\",\"split:2\",\"tlsfrag:1\"]}", - MobileproxyNewStderrLogWriter(), - &dialerError - ) { - var proxyError: NSError? - self.proxy = MobileproxyRunProxy( - "127.0.0.1:8080", - dialer, - &proxyError - ) - } - } - ``` - - * Stop the proxy in `applicationWillResignActive`: - - ```swift - func applicationWillResignActive(_ application: UIApplication) { - if let proxy = self.proxy { - proxy.stop(3000) - self.proxy = nil - } - } - ``` - -### Android Integration - * **Convert your Android project to Kotlin.** Open the Android project with `npx cap open android`. - * Navigate to `java//MainActivity` - * Right click on the file and select "Convert Java File to Kotlin File". Confirm the following dialogs. - * Once done, you will need to right click the `MainActivity` a second time and select "Convert Java File to Kotlin File" - - [See the official instructions if you encounter any issues.](https://developer.android.com/kotlin/add-kotlin) - - * **Update your Gradle files for Kotlin compatibility.** - * Inside: `/android/app/build.gradle`, add `apply plugin: 'kotlin-android'` on line 2, directly under `apply plugin: 'com.android.application'`. - * Inside: `/android/variables.gradle`, update the SDK variables to: - - ``` - minSdkVersion = 26 - compileSdkVersion = 35 - targetSdkVersion = 35 - ``` - - * **Import dependencies:** - * Right click on `app` and select "Open Module Settings" - * In the sidebar, navigate to "Dependencies" - * Click the `+` button and select a Library Dependency - * Search for `androidx.webkit` and select it. - * Next we need to import the `mobileproxy.aar`. Click the `+` button again and select `JAR/AAR Dependency`. - * Type in the path `../../outline-sdk/x/out/mobileproxy.aar` - * Click `Apply`. - * **Important:** The two added dependencies are initially placed in `/android/app/capacitor.build.gradle`, which is a generated file that gets reset frequently. To avoid losing these dependencies, manually move them to `/android/app/build.gradle`. - - * In the head of your new `MainActivity.kt`, import the following: - - ```kotlin - import android.os.* - import mobileproxy.* - import androidx.webkit.* - ``` - - * Now, in your `MainActivity.kt`, confirm proxy override is available in `onCreate`: - - ```kotlin - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { - // Proxy override is supported - } - } - ``` - - * Initialize `mobileproxy` with a smart dialer in `onCreate`. Don't forget to replace `www.your-pwa-url.com`!: - - ```kotlin - private var proxy: Proxy? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { - this.proxy = Mobileproxy.runProxy( - "127.0.0.1:0", - Mobileproxy.newSmartStreamDialer( - Mobileproxy.newListFromLines("www.your-pwa-url.com"), - "{\"dns\":[{\"https\":{\"name\":\"9.9.9.9\"}}],\"tls\":[\"\",\"split:1\",\"split:2\",\"tlsfrag:1\"]}", - Mobileproxy.newStderrLogWriter() - ) - ) - } - } - ``` - - * Proxy all app requests after the proxy is initialized using `ProxyController`: - - ```kotlin - // NOTE: This affects all requests in the application - ProxyController.getInstance() - .setProxyOverride( - ProxyConfig.Builder() - .addProxyRule(this.proxy!!.address()) - .build(), - { - runOnUiThread { - // Capacitor does not expose a way to defer the loading of the webview, - // so we simply refresh the page - this.bridge.webView.reload() - } - }, - {} - ) - ``` - - * Turn off the proxy in `onDestroy`: - - ```kotlin - override fun onDestroy() { - this.proxy?.stop(3000) - this.proxy = null - - super.onDestroy() - } - ``` - -## Verify with Packet Tracing - -* **iOS:** Load XCode and connect your iOS device. Make sure that your device allows your developer certificate (Check `Settings > General > VPN & Device Management` on your iOS device). Go to `Product > Profile` in XCode and select the "Network" option from the list of presets. Pressing the record button on the window that pops up should launch your app and record its traffic. Once done, set the view on the packet trace data to `History` and among the results you should see the DNS address `dn9.quad9.net`. -* **Android:** Start the emulator with `npx cap run android`. Use Wireshark to capture network traffic. Filter by `ip.addr == 9.9.9.9` (your chosen DNS server). You should see TCP and TLS traffic, indicating that your app is using DNS over HTTPS (DoH). - -## Building and Distributing your App - -### iOS - -1. Create a developer account and add it to XCode Settings (`XCode > Settings... > Accounts`) -2. Select your App in the file explorer and pick your Account's Team in `Signing & Capabilities` -3. Connect your iOS device and select it as your build target in the top bar. XCode should automatically create a provisioning profile for the device and app combination. -4. Build a production archive with `Product > Archive` -5. On success, a window should pop up with your app listed in it. Select `Distribute App` and follow the instructions. - -### Android - -First, generate a Key Store and use it to sign your app with Android Studio - follow these instructions: https://developer.android.com/studio/publish/app-signing#generate-key - -Note that you can choose to release your app as either an android app bundle (`.aab`) or an APK (`.apk`). -1. You need an android app bundle (`.aab`) to release your app in the Google Play Store. For this you will have to have a [Google Play Developer Account](https://play.google.com/console/u/0/developers) and at least twenty trusted testers to unlock production access. -2. APKs (`.apk`) can be freely sideloaded onto your user's devices. For an APK, you will have to take care of distribution yourself. - -**Important Notes:** - -* Replace `"www.your-pwa-url.com"` with your actual PWA URL. -* This code lab provides a basic framework. You might need to adjust it depending on your PWA's specific requirements and the Outline SDK's updates. -* Consider adding error handling and UI elements to improve the user experience. - -By following these steps, you can create an Android/iOS app that utilizes the Outline SDK Mobileproxy to circumvent censorship and access your PWA securely. This approach empowers users in restricted environments to access information and services freely. - -## Advanced: Add Support for Service Workers on iOS - -By default, Service workers aren't supported in iOS webviews. To activate them, you need to do the following: - -* In `capacitor.config.json`, enable `limitsNavigationsToAppBoundDomains`: - - ```json - { - "appId": "com.yourcompany.yourapp", - "appName": "YourAppName", - "bundledWebRuntime": false, - "server": { - "url": "https://www.your-pwa-url.com" - }, - "ios": { - "limitsNavigationsToAppBoundDomains": true - } - } - ``` - -* In your iOS project's `ios/App/App/Info.plist`, add your PWA's URL to a `WKAppBoundDomains` array in the top level ``: - - ```xml - WKAppBoundDomains - - www.your-pwa-url.com - - ``` - - Be sure to add any URLs you navigate to within your PWA in this array as well! diff --git a/x/examples/outline-pwa/.gitignore b/x/examples/outline-web-wrapper/.gitignore similarity index 100% rename from x/examples/outline-pwa/.gitignore rename to x/examples/outline-web-wrapper/.gitignore diff --git a/x/examples/outline-pwa/LICENSE b/x/examples/outline-web-wrapper/LICENSE similarity index 100% rename from x/examples/outline-pwa/LICENSE rename to x/examples/outline-web-wrapper/LICENSE diff --git a/x/examples/outline-web-wrapper/README.md b/x/examples/outline-web-wrapper/README.md new file mode 100644 index 00000000..72740bac --- /dev/null +++ b/x/examples/outline-web-wrapper/README.md @@ -0,0 +1,425 @@ +# Wrapping your website in a Censorship-Resistant iOS App with CapacitorJS and the Outline SDK Mobileproxy + +## Prerequisites + +* A website you want to make censorship resistant. +* Set up your development environment with the following. + * [Node.js](https://nodejs.org/en/), for the Capacitor build system. + * [GoLang](https://go.dev/), to build the Outline Mobile Proxy. + * [XCode](https://developer.apple.com/xcode/) and [cocoapods](https://cocoapods.org/). [Please follow CapacitorJS's environment setup guide](https://capacitorjs.com/docs/getting-started/environment-setup#ios-requirements) + +## Important Notes + +* Replace `"www.your-website-url.com"` with your actual website URL. +* This code lab provides a basic framework. You might need to adjust it depending on your website's specific requirements and the Outline SDK's updates. + +## Create your app + +**1. Set up the Capacitor Project** + +Follow the CapacitorJS Getting Started guide to initialize a new project: [https://capacitorjs.com/docs/getting-started](https://capacitorjs.com/docs/getting-started) + +> [!NOTE] +> This will create a new directory containing your project. Make sure you run these commands relative to where you want your project to live. + +```bash +npm init @capacitor/app # follow the instructions - make sure to pick an app ID that's unique! +cd +npm install +``` + +Add iOS platform to your project: + +```bash +npm install @capacitor/ios +npx cap add ios + +npm run build # this builds the stock web app that the default project ships with +npx cap sync ios +``` + +**2. Confirm that the default app is able to run** + +Open the iOS project in XCode with `npx cap open ios`. + +Make sure the correct emulator or device is selected and press the ▶️ button. + +**3. Configure Capacitor to Load Your Website** + +Update `capacitor.config.json`: + +```json +{ + "appId": "com.yourcompany.yourapp", + "appName": "YourAppName", + "bundledWebRuntime": false, + "server": { + "url": "https://www.your-website-url.com" + } +} +``` + +> [!NOTE] +> Capacitor will silently fail to read your config if the JSON is invalid. Be sure to check `capacitor.config.json` for any hanging commas! + +**4. Integrate the Outline SDK Mobileproxy Library** + + Build the Mobileproxy library: + +[Follow the instructions in the Outline SDK repository](https://github.com/Jigsaw-Code/outline-sdk/tree/main/x/mobileproxy#build-the-go-mobile-binaries-with-go-build): + +```bash +git clone https://github.com/Jigsaw-Code/outline-sdk.git +cd outline-sdk/x +go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind + +PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=ios -iosversion=11.0 -o "$(pwd)/out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy +``` +Open the XCode project with `npx cap open ios`. +Add the compiled `mobileproxy.xcframework` static library to your Xcode project: +* Right click on the `Frameworks` folder. +* Select `Add Files to "App"...` +* Select the `mobileproxy.xcframework` folder. + +Create a new file called `OutlineBridgeViewController.swift`: +* Right click on the `App` folder. +* Select `New File...` +* Select the `Swift File` and click `Next`. +* Enter in the file name. + +Extend the base Capacitor Bridge View Controller: + +```swift +import UIKit +import Capacitor + +class OutlineBridgeViewController: CAPBridgeViewController { + private let proxyHost: String = "127.0.0.1" + private let proxyPort: String = "8080" +} +``` + +Override the `webView` method to inject the proxy configuration: + +```swift +override func webView(with frame: CGRect, configuration: WKWebViewConfiguration) -> WKWebView { + if #available(iOS 17.0, *) { + let endpoint = NWEndpoint.hostPort( + host: NWEndpoint.Host(self.proxyHost), + port: NWEndpoint.Port(self.proxyPort)! + ) + let proxyConfig = ProxyConfiguration.init(httpCONNECTProxy: endpoint) + + let websiteDataStore = WKWebsiteDataStore.default() + websiteDataStore.proxyConfigurations = [proxyConfig] + + configuration.websiteDataStore = websiteDataStore + } + + return super.webView(with: frame, configuration: configuration) +} +``` + +In `AppDelegate.swift`, set the `rootViewController` to your new `OutlineBridgeViewController`: + +```swift +func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + self.window?.rootViewController = OutlineBridgeViewController() + + return true +} +``` + +Import the Mobileproxy framework at the head of the `AppDelegate.swift` file: + +```swift +import Mobileproxy +``` + +Create a `proxy` property on the `AppDelegate`: + +```swift +var proxy: MobileproxyProxy? +``` + +Then set up the dialer and start the proxy in `applicationDidBecomeActive`: + +```swift +func applicationDidBecomeActive(_ application: UIApplication) { + var dialerError: NSError? + if let dialer = MobileproxyNewSmartStreamDialer( + MobileproxyNewListFromLines("www.your-website-url.com"), + "{\"dns\":[{\"https\":{\"name\":\"9.9.9.9\"}}],\"tls\":[\"\",\"split:1\",\"split:2\",\"tlsfrag:1\"]}", + MobileproxyNewStderrLogWriter(), + &dialerError + ) { + var proxyError: NSError? + self.proxy = MobileproxyRunProxy( + "127.0.0.1:8080", + dialer, + &proxyError + ) + } +} +``` + +Stop the proxy in `applicationWillResignActive`: + +```swift +func applicationWillResignActive(_ application: UIApplication) { + if let proxy = self.proxy { + proxy.stop(3000) + self.proxy = nil + } +} +``` + +**5. Verify with Packet Tracing** + +Load XCode and connect your iOS device. Make sure that your device allows your developer certificate (Check `Settings > General > VPN & Device Management` on your iOS device). Go to `Product > Profile` in XCode and select the "Network" option from the list of presets. Pressing the record button on the window that pops up should launch your app and record its traffic. Once done, set the view on the packet trace data to `History` and among the results you should see the DNS address `dn9.quad9.net`. + +**6. Building and Distributing your App** + +* Create a developer account and add it to XCode Settings (`XCode > Settings... > Accounts`) +* Select your App in the file explorer and pick your Account's Team in `Signing & Capabilities` +* Connect your iOS device and select it as your build target in the top bar. XCode should automatically create a provisioning profile for the device and app combination. +* Build a production archive with `Product > Archive` +* On success, a window should pop up with your app listed in it. Select `Distribute App` and follow the instructions. + +**7. Advanced: Add Support for Service Workers on iOS** + +By default, Service workers aren't supported in iOS webviews. To activate them, you need to do the following: + +In `capacitor.config.json`, enable `limitsNavigationsToAppBoundDomains`: + +```json +{ + "appId": "com.yourcompany.yourapp", + "appName": "YourAppName", + "bundledWebRuntime": false, + "server": { + "url": "https://www.your-website-url.com" + }, + "ios": { + "limitsNavigationsToAppBoundDomains": true + } +} +``` + +In your iOS project's `ios/App/App/Info.plist`, add your Website's URL to a `WKAppBoundDomains` array in the top level ``: + +```xml +WKAppBoundDomains + + www.your-website-url.com + +``` + +Be sure to add any URLs you navigate to within your website in this array as well! + + +--- + + +# Building a Censorship-Resistant Android App with CapacitorJS and the Outline SDK Mobileproxy + +## Prerequisites + +* A website you want to make censorship resistant. +* Make sure your development environment is set up with the following. + * [Node.js](https://nodejs.org/en/), for the Capacitor build system. + * [GoLang](https://go.dev/), to build the Outline Mobile Proxy. + * [OpenJDK 17](https://stackoverflow.com/a/70649641) and [Android Studio](https://developer.android.com/studio/) [Please follow CapacitorJS's environment setup guide](https://capacitorjs.com/docs/getting-started/environment-setup#android-requirements) +* [Wireshark](https://www.wireshark.org/), to confirm traffic is going through the Outline proxy + +## Important Notes + +* Replace `"www.your-website-url.com"` with your actual website URL in all the relevant code snippets. +* This code lab provides a basic framework. You might need to adjust it depending on your website's specific requirements and the Outline SDK's updates. +* **Security:** Keep your key store file and passwords secure. Losing them can prevent you from updating your app in the future. +* **Testing:** Thoroughly test your app on different devices and Android versions before releasing it. + +## Create your app + +**1. Set up the Capacitor Project** + +Follow the CapacitorJS Getting Started guide to initialize a new project: [https://capacitorjs.com/docs/getting-started](https://capacitorjs.com/docs/getting-started) + +> [!NOTE] +> This will create a new directory containing your project. Make sure you run these commands relative to where you want your project to live. + +```bash +npm init @capacitor/app # follow the instructions - make sure to pick an app ID that's unique! +cd +npm install +``` + +Add Android platform to your project: + +```bash +npm install @capacitor/android +npx cap add android + +mkdir android/app/src/main/assets # sync will fail without this folder +npm run build # this builds the stock web app that the default project ships with +npx cap sync android +``` + +**2. Confirm that the default app is able to run** + +Open the Android project in Android Studio with `npx cap open android`. + +Ensure you have an emulator with Android API 35 or later (check `Tools > Device Manager`), then press the ▶️ button. + +**3. Configure Capacitor to Load Your Website** + +Update `capacitor.config.json`: + +```json +{ + "appId": "com.yourcompany.yourapp", + "appName": "YourAppName", + "bundledWebRuntime": false, + "server": { + "url": "https://www.your-website-url.com" + } +} +``` + +> [!NOTE] +> Capacitor will silently fail to read your config if the JSON is invalid. Be sure to check `capacitor.config.json` for any hanging commas! + +**4. Integrate the Outline SDK Mobileproxy Library** + +**Build the Mobileproxy library:** +[Follow the instructions in the Outline SDK repository](https://github.com/Jigsaw-Code/outline-sdk/tree/main/x/mobileproxy#build-the-go-mobile-binaries-with-go-build): + +```bash + git clone https://github.com/Jigsaw-Code/outline-sdk.git + cd outline-sdk/x + go build -o "$(pwd)/out/" golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind + + PATH="$(pwd)/out:$PATH" gomobile bind -ldflags='-s -w' -target=android -androidapi=21 -o "$(pwd)/out/mobileproxy.aar" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy +``` + +**Convert your Android project to Kotlin.** Open the Android project with `npx cap open android`. + +* Navigate to `java//MainActivity` +* Right click on the file and select "Convert Java File to Kotlin File". Confirm the following dialogs. +* Once done, you will need to right click the `MainActivity` a second time and select "Convert Java File to Kotlin File" + +[See the official instructions if you encounter any issues.](https://developer.android.com/kotlin/add-kotlin) + +**Update your Gradle files for Kotlin compatibility.** + +* Inside: `/android/app/build.gradle`, add `apply plugin: 'kotlin-android'` on line 2, directly under `apply plugin: 'com.android.application'`. +* Inside: `/android/variables.gradle`, update the SDK variables to: + +```kotlin +minSdkVersion = 26 +compileSdkVersion = 35 +targetSdkVersion = 35 +``` + +**Import dependencies:** + +* Right click on `app` and select "Open Module Settings" +* In the sidebar, navigate to "Dependencies" +* Click the `+` button and select a Library Dependency +* Search for `androidx.webkit` and select it. +* Next we need to import the `mobileproxy.aar`. Click the `+` button again and select `JAR/AAR Dependency`. +* Type in the path `../../outline-sdk/x/out/mobileproxy.aar` +* Click `Apply`. +* **Important:** The two added dependencies are initially placed in `/android/app/capacitor.build.gradle`, which is a generated file that gets reset frequently. To avoid losing these dependencies, manually move them to `/android/app/build.gradle`. +* In the head of your new `MainActivity.kt`, import the following: + +```kotlin +import android.os.* +import mobileproxy.* +import androidx.webkit.* +``` + +Now, in your `MainActivity.kt`, confirm proxy override is available in `onCreate`: + +```kotlin +override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { + // Proxy override is supported + } +} +``` + +Initialize `mobileproxy` with a smart dialer in `onCreate`. Don't forget to replace `www.your-website-url.com`!: + +```kotlin +private var proxy: Proxy? = null + +override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) { + this.proxy = Mobileproxy.runProxy( + "127.0.0.1:0", + Mobileproxy.newSmartStreamDialer( + Mobileproxy.newListFromLines("www.your-website-url.com"), + "{\"dns\":[{\"https\":{\"name\":\"9.9.9.9\"}}],\"tls\":[\"\",\"split:1\",\"split:2\",\"tlsfrag:1\"]}", + Mobileproxy.newStderrLogWriter() + ) + ) + } +} +``` + +Proxy all app requests after the proxy is initialized using `ProxyController`: + +```kotlin +// NOTE: This affects all requests in the application +ProxyController.getInstance() + .setProxyOverride( + ProxyConfig.Builder() + .addProxyRule(this.proxy!!.address()) + .build(), + { + runOnUiThread { + // Capacitor does not expose a way to defer the loading of the webview, + // so we simply refresh the page + this.bridge.webView.reload() + } + }, + {} + ) +``` + +Turn off the proxy in `onDestroy`: + +```kotlin +override fun onDestroy() { + this.proxy?.stop(3000) + this.proxy = null + + super.onDestroy() +} +``` + +**6. Verify with Packet Tracing** + +Start the emulator with `npx cap run android`. Use Wireshark to capture network traffic. Filter by `ip.addr == 9.9.9.9` (your chosen DNS server). You should see TCP and TLS traffic, indicating that your app is using DNS over HTTPS (DoH). + +**7. Building and Distributing your App** + +First, generate a Key Store and use it to sign your app with Android Studio - follow these instructions: [https://developer.android.com/studio/publish/app-signing#generate-key](https://developer.android.com/studio/publish/app-signing#generate-key) + +Note that you can choose to release your app as either an android app bundle (`.aab`) or an APK (`.apk`). + +You need an android app bundle (`.aab`) to release your app in the Google Play Store. For this you will have to have a [Google Play Developer Account](https://play.google.com/console/u/0/developers) and at least twenty trusted testers to unlock production access. + +* Create a new application. +* Fill in the required information (store listing, pricing, etc.). +* Navigate to "App releases" and select a release track (e.g., internal testing, closed testing, open testing, or production). +* Upload your `.aab` file. +* Follow the instructions to complete the release process. + +APKs (`.apk`) can be freely sideloaded onto your user's devices. For an APK, you will have to take care of distribution yourself. **Note that users need to enable "Install unknown apps"** on their Android devices to install apps from sources other than the Google Play Store. This setting is usually found under `Settings > Security` or `Settings > Apps & notifications > Special app access`. diff --git a/x/examples/outline-pwa/android/.gitignore b/x/examples/outline-web-wrapper/android/.gitignore similarity index 100% rename from x/examples/outline-pwa/android/.gitignore rename to x/examples/outline-web-wrapper/android/.gitignore diff --git a/x/examples/outline-pwa/android/app/.gitignore b/x/examples/outline-web-wrapper/android/app/.gitignore similarity index 100% rename from x/examples/outline-pwa/android/app/.gitignore rename to x/examples/outline-web-wrapper/android/app/.gitignore diff --git a/x/examples/outline-pwa/android/app/build.gradle b/x/examples/outline-web-wrapper/android/app/build.gradle similarity index 100% rename from x/examples/outline-pwa/android/app/build.gradle rename to x/examples/outline-web-wrapper/android/app/build.gradle diff --git a/x/examples/outline-pwa/android/app/capacitor.build.gradle b/x/examples/outline-web-wrapper/android/app/capacitor.build.gradle similarity index 100% rename from x/examples/outline-pwa/android/app/capacitor.build.gradle rename to x/examples/outline-web-wrapper/android/app/capacitor.build.gradle diff --git a/x/examples/outline-pwa/android/app/proguard-rules.pro b/x/examples/outline-web-wrapper/android/app/proguard-rules.pro similarity index 100% rename from x/examples/outline-pwa/android/app/proguard-rules.pro rename to x/examples/outline-web-wrapper/android/app/proguard-rules.pro diff --git a/x/examples/outline-pwa/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java b/x/examples/outline-web-wrapper/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java similarity index 100% rename from x/examples/outline-pwa/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java rename to x/examples/outline-web-wrapper/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java diff --git a/x/examples/outline-pwa/android/app/src/main/AndroidManifest.xml b/x/examples/outline-web-wrapper/android/app/src/main/AndroidManifest.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/AndroidManifest.xml rename to x/examples/outline-web-wrapper/android/app/src/main/AndroidManifest.xml diff --git a/x/examples/outline-pwa/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt b/x/examples/outline-web-wrapper/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt rename to x/examples/outline-web-wrapper/android/app/src/main/java/org/getoutline/pwa/MainActivity.kt diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-land-hdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-hdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-land-hdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-hdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-land-mdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-mdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-land-mdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-mdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-land-xhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-land-xhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xxhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-land-xxhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xxhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xxxhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-land-xxxhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-land-xxxhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-port-hdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-hdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-port-hdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-hdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-port-mdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-mdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-port-mdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-mdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-port-xhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-port-xhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xxhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-port-xxhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xxhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xxxhdpi/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-port-xxxhdpi/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-port-xxxhdpi/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable/ic_launcher_background.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable/ic_launcher_background.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable/ic_launcher_background.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/drawable/splash.png b/x/examples/outline-web-wrapper/android/app/src/main/res/drawable/splash.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/drawable/splash.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/drawable/splash.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/layout/activity_main.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/layout/activity_main.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/layout/activity_main.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/layout/activity_main.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to x/examples/outline-web-wrapper/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/x/examples/outline-pwa/android/app/src/main/res/values/ic_launcher_background.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/values/ic_launcher_background.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/values/ic_launcher_background.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/values/ic_launcher_background.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/values/strings.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/values/strings.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/values/strings.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/values/strings.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/values/styles.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/values/styles.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/values/styles.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/values/styles.xml diff --git a/x/examples/outline-pwa/android/app/src/main/res/xml/file_paths.xml b/x/examples/outline-web-wrapper/android/app/src/main/res/xml/file_paths.xml similarity index 100% rename from x/examples/outline-pwa/android/app/src/main/res/xml/file_paths.xml rename to x/examples/outline-web-wrapper/android/app/src/main/res/xml/file_paths.xml diff --git a/x/examples/outline-pwa/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java b/x/examples/outline-web-wrapper/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java similarity index 100% rename from x/examples/outline-pwa/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java rename to x/examples/outline-web-wrapper/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java diff --git a/x/examples/outline-pwa/android/build.gradle b/x/examples/outline-web-wrapper/android/build.gradle similarity index 100% rename from x/examples/outline-pwa/android/build.gradle rename to x/examples/outline-web-wrapper/android/build.gradle diff --git a/x/examples/outline-pwa/android/capacitor.settings.gradle b/x/examples/outline-web-wrapper/android/capacitor.settings.gradle similarity index 100% rename from x/examples/outline-pwa/android/capacitor.settings.gradle rename to x/examples/outline-web-wrapper/android/capacitor.settings.gradle diff --git a/x/examples/outline-pwa/android/gradle.properties b/x/examples/outline-web-wrapper/android/gradle.properties similarity index 100% rename from x/examples/outline-pwa/android/gradle.properties rename to x/examples/outline-web-wrapper/android/gradle.properties diff --git a/x/examples/outline-pwa/android/gradle/wrapper/gradle-wrapper.jar b/x/examples/outline-web-wrapper/android/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from x/examples/outline-pwa/android/gradle/wrapper/gradle-wrapper.jar rename to x/examples/outline-web-wrapper/android/gradle/wrapper/gradle-wrapper.jar diff --git a/x/examples/outline-pwa/android/gradle/wrapper/gradle-wrapper.properties b/x/examples/outline-web-wrapper/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from x/examples/outline-pwa/android/gradle/wrapper/gradle-wrapper.properties rename to x/examples/outline-web-wrapper/android/gradle/wrapper/gradle-wrapper.properties diff --git a/x/examples/outline-pwa/android/gradlew b/x/examples/outline-web-wrapper/android/gradlew similarity index 100% rename from x/examples/outline-pwa/android/gradlew rename to x/examples/outline-web-wrapper/android/gradlew diff --git a/x/examples/outline-pwa/android/gradlew.bat b/x/examples/outline-web-wrapper/android/gradlew.bat similarity index 100% rename from x/examples/outline-pwa/android/gradlew.bat rename to x/examples/outline-web-wrapper/android/gradlew.bat diff --git a/x/examples/outline-pwa/android/settings.gradle b/x/examples/outline-web-wrapper/android/settings.gradle similarity index 100% rename from x/examples/outline-pwa/android/settings.gradle rename to x/examples/outline-web-wrapper/android/settings.gradle diff --git a/x/examples/outline-pwa/android/variables.gradle b/x/examples/outline-web-wrapper/android/variables.gradle similarity index 100% rename from x/examples/outline-pwa/android/variables.gradle rename to x/examples/outline-web-wrapper/android/variables.gradle diff --git a/x/examples/outline-pwa/capacitor.config.json b/x/examples/outline-web-wrapper/capacitor.config.json similarity index 100% rename from x/examples/outline-pwa/capacitor.config.json rename to x/examples/outline-web-wrapper/capacitor.config.json diff --git a/x/examples/outline-pwa/generated/mobileproxy.aar b/x/examples/outline-web-wrapper/generated/mobileproxy.aar similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.aar rename to x/examples/outline-web-wrapper/generated/mobileproxy.aar diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/Info.plist b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/Info.plist similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/Info.plist rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/Info.plist diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.objc.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.objc.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.objc.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Mobileproxy.objc.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Universe.objc.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Universe.objc.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Universe.objc.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/Universe.objc.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/ref.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/ref.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/ref.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Headers/ref.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Info.plist b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Info.plist similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Info.plist rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Info.plist diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Mobileproxy b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Mobileproxy similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Mobileproxy rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Mobileproxy diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Modules/module.modulemap b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Modules/module.modulemap similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Modules/module.modulemap rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64/Mobileproxy.framework/Modules/module.modulemap diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.objc.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.objc.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.objc.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Mobileproxy.objc.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Universe.objc.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Universe.objc.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Universe.objc.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/Universe.objc.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/ref.h b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/ref.h similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/ref.h rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Headers/ref.h diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Info.plist b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Info.plist similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Info.plist rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Info.plist diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Mobileproxy b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Mobileproxy similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Mobileproxy rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Mobileproxy diff --git a/x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Modules/module.modulemap b/x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Modules/module.modulemap similarity index 100% rename from x/examples/outline-pwa/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Modules/module.modulemap rename to x/examples/outline-web-wrapper/generated/mobileproxy.xcframework/ios-arm64_x86_64-simulator/Mobileproxy.framework/Modules/module.modulemap diff --git a/x/examples/outline-pwa/ios/.gitignore b/x/examples/outline-web-wrapper/ios/.gitignore similarity index 100% rename from x/examples/outline-pwa/ios/.gitignore rename to x/examples/outline-web-wrapper/ios/.gitignore diff --git a/x/examples/outline-pwa/ios/App/App.xcodeproj/project.pbxproj b/x/examples/outline-web-wrapper/ios/App/App.xcodeproj/project.pbxproj similarity index 100% rename from x/examples/outline-pwa/ios/App/App.xcodeproj/project.pbxproj rename to x/examples/outline-web-wrapper/ios/App/App.xcodeproj/project.pbxproj diff --git a/x/examples/outline-pwa/ios/App/App.xcworkspace/contents.xcworkspacedata b/x/examples/outline-web-wrapper/ios/App/App.xcworkspace/contents.xcworkspacedata similarity index 100% rename from x/examples/outline-pwa/ios/App/App.xcworkspace/contents.xcworkspacedata rename to x/examples/outline-web-wrapper/ios/App/App.xcworkspace/contents.xcworkspacedata diff --git a/x/examples/outline-pwa/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/x/examples/outline-web-wrapper/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from x/examples/outline-pwa/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to x/examples/outline-web-wrapper/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/x/examples/outline-pwa/ios/App/App/AppDelegate.swift b/x/examples/outline-web-wrapper/ios/App/App/AppDelegate.swift similarity index 100% rename from x/examples/outline-pwa/ios/App/App/AppDelegate.swift rename to x/examples/outline-web-wrapper/ios/App/App/AppDelegate.swift diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/Contents.json b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Contents.json similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/Contents.json rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Contents.json diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png diff --git a/x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png b/x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png rename to x/examples/outline-web-wrapper/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png diff --git a/x/examples/outline-pwa/ios/App/App/Base.lproj/LaunchScreen.storyboard b/x/examples/outline-web-wrapper/ios/App/App/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Base.lproj/LaunchScreen.storyboard rename to x/examples/outline-web-wrapper/ios/App/App/Base.lproj/LaunchScreen.storyboard diff --git a/x/examples/outline-pwa/ios/App/App/Base.lproj/Main.storyboard b/x/examples/outline-web-wrapper/ios/App/App/Base.lproj/Main.storyboard similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Base.lproj/Main.storyboard rename to x/examples/outline-web-wrapper/ios/App/App/Base.lproj/Main.storyboard diff --git a/x/examples/outline-pwa/ios/App/App/Info.plist b/x/examples/outline-web-wrapper/ios/App/App/Info.plist similarity index 100% rename from x/examples/outline-pwa/ios/App/App/Info.plist rename to x/examples/outline-web-wrapper/ios/App/App/Info.plist diff --git a/x/examples/outline-pwa/ios/App/App/OutlineBridgeViewController.swift b/x/examples/outline-web-wrapper/ios/App/App/OutlineBridgeViewController.swift similarity index 100% rename from x/examples/outline-pwa/ios/App/App/OutlineBridgeViewController.swift rename to x/examples/outline-web-wrapper/ios/App/App/OutlineBridgeViewController.swift diff --git a/x/examples/outline-pwa/ios/App/Podfile b/x/examples/outline-web-wrapper/ios/App/Podfile similarity index 100% rename from x/examples/outline-pwa/ios/App/Podfile rename to x/examples/outline-web-wrapper/ios/App/Podfile diff --git a/x/examples/outline-pwa/ios/App/Podfile.lock b/x/examples/outline-web-wrapper/ios/App/Podfile.lock similarity index 100% rename from x/examples/outline-pwa/ios/App/Podfile.lock rename to x/examples/outline-web-wrapper/ios/App/Podfile.lock diff --git a/x/examples/outline-pwa/package-lock.json b/x/examples/outline-web-wrapper/package-lock.json similarity index 100% rename from x/examples/outline-pwa/package-lock.json rename to x/examples/outline-web-wrapper/package-lock.json diff --git a/x/examples/outline-pwa/package.json b/x/examples/outline-web-wrapper/package.json similarity index 100% rename from x/examples/outline-pwa/package.json rename to x/examples/outline-web-wrapper/package.json