From b9ee930aab7f6ca109b2e90fd0233665f2d79516 Mon Sep 17 00:00:00 2001
From: laszlo-domonkos <85620991+laszlo-domonkos@users.noreply.github.com>
Date: Tue, 21 Nov 2023 20:04:56 +0100
Subject: [PATCH] NEVISACCESSAPP-5381: Fixed Android deep link configuration
(#26)
---
.github/workflows/publish_android.yml | 3 +-
README.md | 38 ++++++
android/Gemfile.lock | 89 +++++++-------
android/app/build.gradle | 2 +-
android/app/src/debug/AndroidManifest.xml | 8 --
android/app/src/main/AndroidManifest.xml | 8 +-
android/fastlane/Fastfile | 56 +++++----
android/fastlane/README.md | 2 +
android/fastlane/actions/modify_file.rb | 102 +++++++++++++++
.../fastlane/actions/modify_gradle_file.rb | 116 ------------------
10 files changed, 227 insertions(+), 197 deletions(-)
delete mode 100644 android/app/src/debug/AndroidManifest.xml
create mode 100644 android/fastlane/actions/modify_file.rb
delete mode 100644 android/fastlane/actions/modify_gradle_file.rb
diff --git a/.github/workflows/publish_android.yml b/.github/workflows/publish_android.yml
index 7490937..963c2b8 100644
--- a/.github/workflows/publish_android.yml
+++ b/.github/workflows/publish_android.yml
@@ -110,5 +110,6 @@ jobs:
lane: 'main'
subdirectory: 'android'
options: '{ "version": "${{ inputs.version }}",
- "build_number": "${{ inputs.build-number }}"
+ "build_number": "${{ inputs.build-number }}",
+ "host_name": "${{ secrets.HOST_NAME }}"
}'
\ No newline at end of file
diff --git a/README.md b/README.md
index 54cff54..6443b76 100644
--- a/README.md
+++ b/README.md
@@ -95,6 +95,44 @@ The example apps are supporting two kinds of configuration: `authenticationCloud
To change the configuration open the [getit_root.dart](lib/getit_root.dart) file which describes the dependency injection related configuration using the `get_it` dart package.
The `environment` parameter should be changed to one of the values already mentioned.
+#### Android Manifest XML
+
+The example applications handle deep links and web links those contain a valid `dispatchTokenResponse` query parameter of an out-of-band operation. The related configuration located in the [AndroidManifest.xml](android/app/src/main/AndroidManifest.xml) for [MainActivity](android/app/src/main/kotlin/ch/nevis/nevis_mobile_authentication_sdk_example_app_flutter/MainActivity.kt) with action `android.intent.action.VIEW`.
+
+##### Web links
+
+Change the `myinstance.mauth.nevis.cloud` host value in the following `intent-filter` with the right host information of your environment.
+
+```xml
+
+
+
+
+
+
+
+
+
+```
+
+##### Deep links
+
+Change the `nevisaccess` scheme value in the following `intent-filter` with the right scheme information of your environment.
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+> [!NOTE]
+> For more information about deep links, web links visit the official [Android guide](https://developer.android.com/training/app-links).
+
### Build
Now you're ready to build the example app by running:
diff --git a/android/Gemfile.lock b/android/Gemfile.lock
index 3220a1d..4e6bb44 100644
--- a/android/Gemfile.lock
+++ b/android/Gemfile.lock
@@ -3,25 +3,25 @@ GEM
specs:
CFPropertyList (3.0.6)
rexml
- addressable (2.8.1)
+ addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
- aws-partitions (1.708.0)
- aws-sdk-core (3.170.0)
+ aws-partitions (1.854.0)
+ aws-sdk-core (3.187.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.62.0)
- aws-sdk-core (~> 3, >= 3.165.0)
+ aws-sdk-kms (1.72.0)
+ aws-sdk-core (~> 3, >= 3.184.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.119.0)
- aws-sdk-core (~> 3, >= 3.165.0)
+ aws-sdk-s3 (1.137.0)
+ aws-sdk-core (~> 3, >= 3.181.0)
aws-sdk-kms (~> 1)
- aws-sigv4 (~> 1.4)
- aws-sigv4 (1.5.2)
+ aws-sigv4 (~> 1.6)
+ aws-sigv4 (1.6.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
@@ -30,13 +30,12 @@ GEM
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
- digest-crc (0.6.4)
+ digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
- domain_name (0.5.20190701)
- unf (>= 0.0.5, < 1.0.0)
+ domain_name (0.6.20231109)
dotenv (2.8.1)
emoji_regex (3.2.3)
- excon (0.99.0)
+ excon (0.104.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -65,8 +64,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
- fastimage (2.2.6)
- fastlane (2.211.0)
+ fastimage (2.2.7)
+ fastlane (2.217.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -87,10 +86,11 @@ GEM
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
+ http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
- multipart-post (~> 2.0.0)
+ multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
@@ -98,7 +98,7 @@ GEM
security (= 0.1.3)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
- terminal-table (>= 1.4.5, < 2.0.0)
+ terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
@@ -107,9 +107,9 @@ GEM
xcpretty-travis-formatter (>= 0.0.3)
fastlane-plugin-firebase_app_distribution (0.5.0)
gh_inspector (1.1.3)
- google-apis-androidpublisher_v3 (0.33.0)
- google-apis-core (>= 0.9.1, < 2.a)
- google-apis-core (0.11.0)
+ google-apis-androidpublisher_v3 (0.53.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.2)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -118,30 +118,29 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
- google-apis-iamcredentials_v1 (0.16.0)
- google-apis-core (>= 0.9.1, < 2.a)
- google-apis-playcustomapp_v1 (0.12.0)
- google-apis-core (>= 0.9.1, < 2.a)
- google-apis-storage_v1 (0.19.0)
- google-apis-core (>= 0.9.0, < 2.a)
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.29.0)
+ google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
- google-cloud-errors (1.3.0)
- google-cloud-storage (1.44.0)
+ google-cloud-errors (1.3.1)
+ google-cloud-storage (1.45.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
- google-apis-storage_v1 (~> 0.19.0)
+ google-apis-storage_v1 (~> 0.29.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
- googleauth (1.3.0)
+ googleauth (1.8.1)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
- memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
@@ -151,30 +150,29 @@ GEM
httpclient (2.8.3)
jmespath (1.6.2)
json (2.6.3)
- jwt (2.7.0)
- memoist (0.16.2)
+ jwt (2.7.1)
mini_magick (4.12.0)
- mini_mime (1.1.2)
+ mini_mime (1.1.5)
multi_json (1.15.0)
- multipart-post (2.0.0)
+ multipart-post (2.3.0)
nanaimo (0.3.0)
naturally (2.2.1)
optparse (0.1.1)
os (1.1.4)
- plist (3.6.0)
- public_suffix (5.0.1)
- rake (13.0.6)
+ plist (3.7.0)
+ public_suffix (5.0.4)
+ rake (13.1.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
- rexml (3.2.5)
+ rexml (3.2.6)
rouge (2.0.7)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
- signet (0.17.0)
+ signet (0.18.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
@@ -183,21 +181,18 @@ GEM
CFPropertyList
naturally
terminal-notifier (2.0.0)
- terminal-table (1.8.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.1)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
uber (0.1.0)
- unf (0.1.4)
- unf_ext
- unf_ext (0.0.8.2)
- unicode-display_width (1.8.0)
+ unicode-display_width (2.5.0)
webrick (1.8.1)
word_wrap (1.0.0)
- xcodeproj (1.22.0)
+ xcodeproj (1.23.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index db72fc2..51d914d 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -30,7 +30,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
- compileSdkVersion 33
+ compileSdk 33
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
deleted file mode 100644
index bf8845c..0000000
--- a/android/app/src/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index d4ed62b..a69d25c 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,11 +1,15 @@
+
+
+
+
+ android:host="myinstance.mauth.nevis.cloud" />
diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile
index 3402050..41aec74 100644
--- a/android/fastlane/Fastfile
+++ b/android/fastlane/Fastfile
@@ -9,6 +9,8 @@ root_dir = File.expand_path(File.join(File.dirname(__FILE__), "../"))
signing_configs_gradle = File.join(root_dir, "app/signing_configs.gradle")
apk_path = File.join(root_dir, "../build/app/outputs/flutter-apk/app-debug.apk")
display_name = "Nevis Mobile Authentication SDK Example App Flutter Android"
+android_manifest = File.join(root_dir, "app/src/main/AndroidManifest.xml")
+build_gradle = File.join(root_dir, "app/build.gradle")
def report_on_success(message)
slack(
@@ -37,37 +39,47 @@ end
platform :android do
desc "Build and distribute the application"
- desc "#### Options"
- desc " * **`version`**: The version of the application."
- desc " * **`build_number`**: The build number of the application."
- desc ""
+ desc "#### Options"
+ desc " * **`version`**: The version of the application."
+ desc " * **`build_number`**: The build number of the application."
+ desc " * **`host_name`**: The host name to be used in AndroidManifest.xml for deep link configuration."
+ desc ""
lane :main do |options|
begin
- version = options[:version]
- build_number = options[:build_number]
+ version = options[:version]
+ build_number = options[:build_number]
UI.message("Distributing #{display_name} #{version} (#{build_number}) 📦")
+ host_name = options[:host_name]
+ modify_file(
+ file_path: android_manifest,
+ old_value: "android:host=\"myinstance.mauth.nevis.cloud\"",
+ new_value: "android:host=\"#{host_name}.mauth.nevis.cloud\""
+ )
+
sh("echo \"#{ENV["SIGNING_CONFIGS"]}\" > #{signing_configs_gradle}")
- modify_gradle_file(
- constant: "signingConfig",
- value: "signingConfigs.signing",
- )
+ modify_file(
+ file_path: build_gradle,
+ old_value: "signingConfig signingConfigs.debug",
+ new_value: "signingConfig signingConfigs.signing",
+ )
- modify_gradle_file(
- constant: "apply plugin: 'kotlin-android'",
- value: "apply from: 'signing_configs.gradle'",
- mode: 'append'
- )
+ modify_file(
+ file_path: build_gradle,
+ old_value: "android {",
+ new_value: "apply from: 'signing_configs.gradle'\n",
+ mode: 'prepend'
+ )
- sh('flutter build apk --debug')
+ sh('flutter build apk --debug')
- firebase_app_distribution(
- app: ENV["FIREBASE_APP_ID_ANDROID"],
- apk_path: apk_path,
- groups: 'developers, internal-testers, presales'
- )
- report_on_success("#{display_name} build is completed: #{version} (#{build_number}) ✅")
+ firebase_app_distribution(
+ app: ENV["FIREBASE_APP_ID_ANDROID"],
+ apk_path: apk_path,
+ groups: 'developers, internal-testers, presales'
+ )
+ report_on_success("#{display_name} build is completed: #{version} (#{build_number}) ✅")
rescue => exception
report_on_error("#{display_name} build failed ❌", exception)
end
diff --git a/android/fastlane/README.md b/android/fastlane/README.md
index 0a2484f..a1e6e51 100644
--- a/android/fastlane/README.md
+++ b/android/fastlane/README.md
@@ -29,6 +29,8 @@ Build and distribute the application
* **`build_number`**: The build number of the application.
+ * **`host_name`**: The host name to be used in AndroidManifest.xml for deep link configuration.
+
----
diff --git a/android/fastlane/actions/modify_file.rb b/android/fastlane/actions/modify_file.rb
new file mode 100644
index 0000000..d370050
--- /dev/null
+++ b/android/fastlane/actions/modify_file.rb
@@ -0,0 +1,102 @@
+require 'tempfile'
+require 'fileutils'
+
+module Fastlane
+ module Actions
+ class ModifyFileAction < Action
+ def self.run(params)
+ file_path ||= params[:file_path]
+ old_value = params[:old_value]
+ new_value = params[:new_value]
+ mode ||= params[:mode]
+
+ UI.message(" Modifying file (#{file_path})!")
+ modify(file_path, old_value, new_value, mode)
+ end
+
+ def self.modify(path, old_value, new_value, mode)
+ if !File.file?(path)
+ raise "No file exist at path: (#{File.expand_path(path)})!"
+ end
+
+ begin
+ temp_file = Tempfile.new('fastlaneModifyFile')
+ File.open(path, 'r') do |file|
+ file.each_line do |line|
+ if line.include? old_value
+ if mode == "replace"
+ line.replace line.sub(old_value, new_value)
+ temp_file.puts line
+ elsif mode == "append"
+ temp_file.puts line
+ temp_file.puts new_value
+ elsif mode == "prepend"
+ temp_file.puts new_value
+ temp_file.puts line
+ end
+ else
+ temp_file.puts line
+ end
+ end
+ file.close
+ end
+ temp_file.rewind
+ temp_file.close
+ FileUtils.mv(temp_file.path, path)
+ temp_file.unlink
+ rescue
+ raise 'Modifying file failed!'
+ end
+ end
+
+ def self.description
+ "Modify file of your Android project."
+ end
+
+ def self.available_options
+ [
+ FastlaneCore::ConfigItem.new(key: :file_path,
+ description: "The path to the file to be modified",
+ optional: false,
+ type: String),
+ FastlaneCore::ConfigItem.new(key: :old_value,
+ description: "The old value whose to be replaced, appended after or prepended before with new value",
+ optional: false,
+ type: String),
+ FastlaneCore::ConfigItem.new(key: :new_value,
+ description: "The new value",
+ optional: false,
+ type: String),
+ FastlaneCore::ConfigItem.new(key: :mode,
+ description: "The working mode. Possible values are replace, append or prepend (default: replace)",
+ optional: true,
+ type: String,
+ default_value:"replace"),
+ ]
+ end
+
+ def self.author
+ "Nevis Security AG"
+ end
+
+ def self.is_supported?(platform)
+ [:android].include? platform
+ end
+
+ def self.example_code
+ [
+ modify_file(
+ file_path: file,
+ old_value: "",
+ new_value: "",
+ mode: "append"
+ )
+ ]
+ end
+
+ def self.category
+ :project
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/android/fastlane/actions/modify_gradle_file.rb b/android/fastlane/actions/modify_gradle_file.rb
deleted file mode 100644
index 0e76e73..0000000
--- a/android/fastlane/actions/modify_gradle_file.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'tempfile'
-require 'fileutils'
-
-module Fastlane
- module Actions
- class ModifyGradleFileAction < Action
- def self.run(params)
- gradle_file_path ||= params[:gradle_file_path]
- constant = params[:constant]
- value = params[:value]
- mode ||= params[:mode]
-
- if gradle_file_path != nil
- UI.message(" Using gradle file (#{gradle_file_path})!")
- modify(gradle_file_path, constant, value, mode)
- else
- app_folder_name ||= params[:app_folder_name]
- UI.message("Using project folder `#{app_folder_name}`!")
-
- Dir.glob("**/#{app_folder_name}/build.gradle") do |path|
- modify(path, constant, value, mode)
- end
- end
- end
-
- def self.modify(path, constant_name, constant_value, mode)
- if !File.file?(path)
- raise "No file exist at path: (#{path})!"
- end
-
- begin
- temp_file = Tempfile.new('fastlaneModifyGradleFile')
- File.open(path, 'r') do |file|
- file.each_line do |line|
- if line.include? constant_name
- if mode == "replace"
- components = line.strip.split(' ')
- current_value = components[components.length-1].tr("\"","")
- line.replace line.sub(current_value, constant_value)
- temp_file.puts line
- elsif mode == "append"
- temp_file.puts line
- temp_file.puts constant_value
- end
- else
- temp_file.puts line
- end
- end
- file.close
- end
- temp_file.rewind
- temp_file.close
- FileUtils.mv(temp_file.path, path)
- temp_file.unlink
- rescue
- raise 'Modifying gradle file failed!'
- end
- end
-
- def self.description
- "Modify gradle file of your Android project."
- end
-
- def self.available_options
- [
- FastlaneCore::ConfigItem.new(key: :app_folder_name,
- description: "The name of the application source folder in the Android project (default: app)",
- optional: true,
- type: String,
- default_value:"app"),
- FastlaneCore::ConfigItem.new(key: :gradle_file_path,
- description: "The relative path to the gradle file containing the constant parameter (default:app/build.gradle)",
- optional: true,
- type: String,
- default_value: nil),
- FastlaneCore::ConfigItem.new(key: :constant,
- description: "The constant whose value is to be replaced or appended after",
- optional: false,
- type: String),
- FastlaneCore::ConfigItem.new(key: :value,
- description: "The new value",
- optional: false,
- type: String),
- FastlaneCore::ConfigItem.new(key: :mode,
- description: "The working mode. Possible values are replace or append (default: replace)",
- optional: true,
- type: String,
- default_value:"replace"),
- ]
- end
-
- def self.author
- "Nevis Security AG"
- end
-
- def self.is_supported?(platform)
- [:android].include? platform
- end
-
- def self.example_code
- [
- modify_gradle_file(
- gradle_file_path: file,
- constant: "",
- value: "",
- mode: "append"
- )
- ]
- end
-
- def self.category
- :project
- end
- end
- end
-end
\ No newline at end of file