diff --git a/.gitignore b/.gitignore index 99b1862b..2e484732 100644 --- a/.gitignore +++ b/.gitignore @@ -52,11 +52,8 @@ build/ **/example/.dart_tool/ # Android related -**/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ -**/android/gradlew -**/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java diff --git a/.pubignore b/.pubignore new file mode 100644 index 00000000..014d3355 --- /dev/null +++ b/.pubignore @@ -0,0 +1,3 @@ +bitrise.yml +.github +releasing.md diff --git a/CHANGELOG.md b/CHANGELOG.md index bd991747..1db5a9d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.0.1, May 30, 2023 +* Changed access modifier of a native api in order to hide it from the sdk user. + ## 3.0.0, May 3, 2023 You can find the full changelog [here](https://developer.onewelcome.com/flutter/plugin/v2-x) and an overview containing the upgrade instructions [here](https://developer.onewelcome.com/flutter/plugin/v2-0). diff --git a/LICENSE b/LICENSE index 729d8cca..e6df6a69 100644 --- a/LICENSE +++ b/LICENSE @@ -198,8 +198,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -<<<<<<< HEAD - limitations under the License. -======= limitations under the License. ->>>>>>> dev/release_first diff --git a/bitrise.yml b/bitrise.yml new file mode 100644 index 00000000..897884b1 --- /dev/null +++ b/bitrise.yml @@ -0,0 +1,159 @@ +--- +format_version: '11' +default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git +project_type: flutter +workflows: + Android: + description: | + Builds project and runs tests. + + Next steps: + - Check out [Getting started with Flutter apps](https://devcenter.bitrise.io/en/getting-started/getting-started-with-flutter-apps.html). + steps: + - git-clone@7: {} + - flutter-installer@0: {} + - script@1: + title: Script - flutter pub get + inputs: + - content: |- + #!/usr/bin/env bash + # fail if any commands fails + set -e + # make pipelines' return status equal the last command to exit with a non-zero status, or zero if all commands exit successfully + set -o pipefail + # debug log + set -x + + # write your script here + cd $BITRISE_FLUTTER_PROJECT_LOCATION + flutter pub get + - install-missing-android-tools@3: + inputs: + - gradlew_path: "./example/android/gradlew" + - android-unit-test@1: + inputs: + - module: "$MODULE" + - project_location: "$BITRISE_SOURCE_DIR/example/android" + - script@1: + inputs: + - content: |- + #!/bin/env bash + set -ex + + # Deleting any old test results from BITRISE_TEST_RESULT_DIR + rm -rf "$BITRISE_TEST_RESULT_DIR/"* + + # Creating the sub-directory for the test run within the BITRISE_TEST_RESULT_DIR: + test_run_dir="$BITRISE_TEST_RESULT_DIR/unit_test_results" + mkdir "$test_run_dir" + + + # Exporting the JUnit XML test report: + cp $BITRISE_SOURCE_DIR/example/build/$MODULE/test-results/testDebugUnitTest/*.xml $test_run_dir/ + + # Creating the test-info.json file with the name of the test run defined: + echo '{"test-name":"Unit tests"}' >> "$test_run_dir/test-info.json" + is_always_run: true + - deploy-to-bitrise-io@2: {} + iOS: + description: | + Builds project and runs tests. + + Next steps: + - Check out [Getting started with Flutter apps](https://devcenter.bitrise.io/en/getting-started/getting-started-with-flutter-apps.html). + steps: + - git-clone@7: {} + - flutter-installer@0: {} + - cache-pull@2: {} + - script@1: + inputs: + - content: |- + #!/usr/bin/env bash + # fail if any commands fails + set -e + # make pipelines' return status equal the last command to exit with a non-zero status, or zero if all commands exit successfully + set -o pipefail + # debug log + set -x + + # write your script here + cd $BITRISE_FLUTTER_PROJECT_LOCATION + flutter pub get + flutter precache --ios + title: Script - flutter pub get + - script@1: + inputs: + - content: | + #!/usr/bin/env bash + # fail if any commands fails + set -e + # debug log + set -x + + gem install cocoapods-art -v 1.0.1 + > /Users/vagrant/.netrc + echo "machine repo.onewelcome.com" > /Users/vagrant/.netrc + echo "login $ARTIFACTORY_USER" >> /Users/vagrant/.netrc + echo "password $ARTIFACTORY_PASSWORD" >> /Users/vagrant/.netrc + chmod 600 /Users/vagrant/.netrc + pod repo-art add onegini https://repo.onewelcome.com/artifactory/api/pods/cocoapods-public + title: Script - setup artifactory credentials + - cocoapods-install@2: + inputs: + - source_root_path: "$BITRISE_SOURCE_DIR/example/ios" + - xcodebuild@0: + inputs: + - xcodebuild_actions: build + - xcodebuild_output_formatter: tee + - cache-push@2: {} + - deploy-to-bitrise-io@2: {} + envs: + - opts: + is_expand: false + SIMULATOR_DEVICE: iPhone 14 + - opts: + is_expand: false + SIMULATOR_OS_VERSION: latest + - opts: + is_expand: false + BITRISE_PROJECT_PATH: example/ios/Runner.xcworkspace + - opts: + is_expand: false + BITRISE_SCHEME: Runner + primary: + description: | + Builds project and runs tests. + + Next steps: + - Check out [Getting started with Flutter apps](https://devcenter.bitrise.io/en/getting-started/getting-started-with-flutter-apps.html). + steps: + - build-router-start@0: + inputs: + - access_token: "$BITRISE_API_TOKEN" + - workflows: iOS + title: Bitrise Start iOS + - build-router-start@0: + title: Bitrise Start Android + inputs: + - access_token: "$BITRISE_API_TOKEN" + - workflows: Android + - git-clone@7: {} + - flutter-installer@0: {} + - deploy-to-bitrise-io@2: {} + - build-router-wait@0: + inputs: + - access_token: "$BITRISE_API_TOKEN" +meta: + bitrise.io: + stack: osx-xcode-14.2.x-ventura +app: + envs: + - opts: + is_expand: false + BITRISE_FLUTTER_PROJECT_LOCATION: example + - opts: + is_expand: false + MODULE: onegini +trigger_map: +- pull_request_source_branch: "*" + workflow: primary diff --git a/example/android/.gitignore b/example/android/.gitignore index fa57afe4..176e81d3 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -1,8 +1,5 @@ -gradle-wrapper.jar /.gradle /captures/ -/gradlew -/gradlew.bat /local.properties GeneratedPluginRegistrant.java diff --git a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfig.kt b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfig.kt deleted file mode 100644 index 663474f6..00000000 --- a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfig.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.onegini.mobile.onegini_example - -import android.os.Build -import com.onegini.mobile.sdk.android.model.OneginiClientConfigModel - - -class OneginiConfigModel : OneginiClientConfigModel { - - private val appIdentifier = "FlutterExampleApp" - private val appPlatform = "android" - private val redirectionUri = "oneginiexample://loginsuccess" - private val appVersion = "1.0.2" - private val baseURL = "https://token-mobile.test.onegini.com" - private val resourceBaseURL = "https://token-mobile.test.onegini.com/resources/" - private val keystoreHash = "ebbcab87e2d16b9441559767a7c85fbaea9a3feef94451990423019a31e5bf1f" - override fun getAppIdentifier(): String { - return appIdentifier - } - - override fun getAppPlatform(): String { - return appPlatform - } - - override fun getRedirectUri(): String { - return redirectionUri - } - - override fun getAppVersion(): String { - return appVersion - } - - override fun getBaseUrl(): String { - return baseURL - } - - override fun getResourceBaseUrl(): String { - return resourceBaseURL - } - - override fun getCertificatePinningKeyStore(): Int { - return R.raw.keystore - } - - override fun getKeyStoreHash(): String { - return keystoreHash - } - - override fun getDeviceName(): String { - return Build.BRAND + " " + Build.MODEL - } - - override fun getServerPublicKey(): String? { - return null - } -} \ No newline at end of file diff --git a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfigModel.java b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfigModel.java new file mode 100755 index 00000000..deef60a0 --- /dev/null +++ b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/OneginiConfigModel.java @@ -0,0 +1,93 @@ +package com.onegini.mobile.onegini_example; + +import android.os.Build; +import com.onegini.mobile.onegini_example.R; +import com.onegini.mobile.sdk.android.model.OneginiClientConfigModel; + +public class OneginiConfigModel implements OneginiClientConfigModel { + + /* Config model generated by SDK Configurator version: v5.1.0 */ + + private final String appIdentifier = "FlutterExampleApp"; + private final String appPlatform = "android"; + private final String redirectionUri = "oneginiexample://loginsuccess"; + private final String appVersion = "1.0.2"; + private final String baseURL = "https://mobile-security-proxy.test.onegini.com"; + private final String resourceBaseURL = "https://mobile-security-proxy.test.onegini.com/resources/"; + private final String keystoreHash = "90cf65bea23977e84dcddfb38b8cecb5469d8ca43aa6b01575864ef2ca6eaa48"; + private final int maxPinFailures = 3; + private final String serverPublicKey = "17DDB4086A1D3FA37950CBDDC6F1173A0C5902A3B71DAD261290CEFEE13CC9CA"; + + public String getAppIdentifier() { + return appIdentifier; + } + + public String getAppPlatform() { + return appPlatform; + } + + public String getRedirectUri() { + return redirectionUri; + } + + public String getAppVersion() { + return appVersion; + } + + public String getBaseUrl() { + return baseURL; + } + + public String getResourceBaseUrl() { + return resourceBaseURL; + } + + public int getCertificatePinningKeyStore() { + return R.raw.keystore; + } + + public String getKeyStoreHash() { + return keystoreHash; + } + + public String getDeviceName() { + return Build.BRAND + " " + Build.MODEL; + } + + public String getServerPublicKey() { + return serverPublicKey; + } + + /** + * @Deprecated Since Android SDK 8.0.0 this attribute is not required. + */ + public boolean shouldGetIdToken() { + return false; + } + + /** + * Get the max PIN failures. This attribute is just used for visual representation towards the end-user. + * + * @Deprecated Since Android SDK 6.01.00 this attribute is fetched from the Device config. + * + * @return The max PIN failures + */ + public int getMaxPinFailures() { + return maxPinFailures; + } + + @Override + public String toString() { + return "ConfigModel{" + + " appIdentifier='" + appIdentifier + "'" + + ", appPlatform='" + appPlatform + "'" + + ", redirectionUri='" + redirectionUri + "'" + + ", appVersion='" + appVersion + "'" + + ", baseURL='" + baseURL + "'" + + ", maxPinFailures='" + maxPinFailures + "'" + + ", resourceBaseURL='" + resourceBaseURL + "'" + + ", keyStoreHash='" + getKeyStoreHash() + "'" + + ", serverPublicKey='" + serverPublicKey + "'" + + "}"; + } +} diff --git a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.java b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.java new file mode 100755 index 00000000..f937a8ae --- /dev/null +++ b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.java @@ -0,0 +1,8 @@ +package com.onegini.mobile.onegini_example; + +@SuppressWarnings({ "unused", "WeakerAccess" }) +public final class SecurityController { + public static final boolean rootDetection = false; + public static final boolean debugDetection = false; + public static final boolean debugLogs = true; +} diff --git a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.kt b/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.kt deleted file mode 100644 index 9169d324..00000000 --- a/example/android/app/src/main/kotlin/com/onegini/mobile/onegini_example/SecurityController.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.onegini.mobile.onegini_example - -object SecurityController { - const val debugDetection = false - const val rootDetection = false - const val debugLogs = true -} diff --git a/example/android/app/src/main/res/raw/keystore.bks b/example/android/app/src/main/res/raw/keystore.bks index bfcdf1b1..9abf5941 100644 Binary files a/example/android/app/src/main/res/raw/keystore.bks and b/example/android/app/src/main/res/raw/keystore.bks differ diff --git a/example/android/build.gradle b/example/android/build.gradle index b8f7cd2c..302ffed1 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,62 +1,62 @@ -buildscript { - ext.kotlin_version = '1.8.0' - repositories { - mavenCentral() - google() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.2.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - def (artifactoryUser, artifactoryPassword) = getArtifactoryCredentials() - if (artifactoryUser?.trim() && artifactoryPassword?.trim()) { - maven { - url "https://repo.onewelcome.com/artifactory/onegini-sdk" - credentials { - username artifactoryUser.trim() - password artifactoryPassword.trim() - } - } - } else { - throw new InvalidUserDataException("You must configure the 'ARTIFACTORY_USER' and 'ARTIFACTORY_PASSWORD' environment variables before you can " + - "build the project.") - } - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} - -def getArtifactoryCredentials() { - // Leave onegini_ property for backwards compatibility - if (project.hasProperty('onegini_artifactory_user') && project.hasProperty('onegini_artifactory_password')) { - return [onegini_artifactory_user, onegini_artifactory_password] - } else if (project.hasProperty('artifactory_user') && project.hasProperty('artifactory_password')) { - return [artifactory_user, artifactory_password] - } else if (System.env.ARTIFACTORY_USER && System.env.ARTIFACTORY_PASSWORD) { - return [System.env.ARTIFACTORY_USER, System.env.ARTIFACTORY_PASSWORD] - } else { - def artifactoryFile = file("${project.rootDir}/artifactory.properties") - if (artifactoryFile.exists()) { - def props = new Properties() - artifactoryFile.withInputStream { props.load(it) } - return [props.getProperty("artifactoryUser"), props.getProperty("artifactoryPassword")] - } - } - return ["", ""] -} +buildscript { + ext.kotlin_version = '1.8.0' + repositories { + mavenCentral() + google() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.2.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + def (artifactoryUser, artifactoryPassword) = getArtifactoryCredentials() + if (artifactoryUser?.trim() && artifactoryPassword?.trim()) { + maven { + url "https://repo.onewelcome.com/artifactory/onegini-sdk" + credentials { + username artifactoryUser.trim() + password artifactoryPassword.trim() + } + } + } else { + throw new InvalidUserDataException("You must configure the 'ARTIFACTORY_USER' and 'ARTIFACTORY_PASSWORD' environment variables before you can " + + "build the project.") + } + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} + +def getArtifactoryCredentials() { + // Leave onegini_ property for backwards compatibility + if (project.hasProperty('onegini_artifactory_user') && project.hasProperty('onegini_artifactory_password')) { + return [onegini_artifactory_user, onegini_artifactory_password] + } else if (project.hasProperty('artifactory_user') && project.hasProperty('artifactory_password')) { + return [artifactory_user, artifactory_password] + } else if (System.env.ARTIFACTORY_USER && System.env.ARTIFACTORY_PASSWORD) { + return [System.env.ARTIFACTORY_USER, System.env.ARTIFACTORY_PASSWORD] + } else { + def artifactoryFile = file("${project.rootDir}/artifactory.properties") + if (artifactoryFile.exists()) { + def props = new Properties() + artifactoryFile.withInputStream { props.load(it) } + return [props.getProperty("artifactoryUser"), props.getProperty("artifactoryPassword")] + } + } + return ["", ""] +} diff --git a/example/ios/Configuration/OneginiConfigModel.m b/example/ios/Configuration/OneginiConfigModel.m index 486e4e1c..4175b2ae 100755 --- a/example/ios/Configuration/OneginiConfigModel.m +++ b/example/ios/Configuration/OneginiConfigModel.m @@ -6,7 +6,7 @@ @implementation OneginiConfigModel + (NSArray *)certificates { - return @[@"MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIwMDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVDQyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAenQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09tbmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIwCAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEBAAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFelpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1HgoE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw6DEdfgkfCv4+3ao8XnTSrLE=", @"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"]; //Base64Certificates + return @[@"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", @"MIIDzTCCArWgAwIBAgIQCjeHZF5ftIwiTv0b7RQMPDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTIwMDEyNzEyNDgwOFoXDTI0MTIzMTIzNTk1OVowSjELMAkGA1UEBhMCVVMxGTAXBgNVBAoTEENsb3VkZmxhcmUsIEluYy4xIDAeBgNVBAMTF0Nsb3VkZmxhcmUgSW5jIEVDQyBDQS0zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEua1NZpkUC0bsH4HRKlAenQMVLzQSfS2WuIg4m4Vfj7+7Te9hRsTJc9QkT+DuHM5ss1FxL2ruTAUJd9NyYqSb16OCAWgwggFkMB0GA1UdDgQWBBSlzjfq67B1DpRniLRF+tkkEIeWHzAfBgNVHSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL09tbmlyb290MjAyNS5jcmwwbQYDVR0gBGYwZDA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sAQIwCAYGZ4EMAQIBMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQELBQADggEBAAUkHd0bsCrrmNaF4zlNXmtXnYJX/OvoMaJXkGUFvhZEOFp3ArnPEELG4ZKk40Un+ABHLGioVplTVI+tnkDB0A+21w0LOEhsUCxJkAZbZB2LzEgwLt4I4ptJIsCSDBFelpKU1fwg3FZs5ZKTv3ocwDfjhUkV+ivhdDkYD7fa86JXWGBPzI6UAPxGezQxPk1HgoE6y/SJXQ7vTQ1unBuCJN0yJV0ReFEQPaA1IwQvZW+cwdFD19Ae8zFnWSfda9J1CZMRJCQUzym+5iPDuI9yP+kHyCREU3qzuWFloUwOxkgAyXVjBYdwRVKD05WdRerw6DEdfgkfCv4+3ao8XnTSrLE="]; //Base64Certificates } + (NSDictionary *)configuration @@ -14,16 +14,16 @@ + (NSDictionary *)configuration return @{ @"ONGAppIdentifier" : @"FlutterExampleApp", @"ONGAppPlatform" : @"ios", - @"ONGAppVersion" : @"1.0.3", - @"ONGAppBaseURL" : @"https://token-mobile.test.onegini.com", - @"ONGResourceBaseURL" : @"https://token-mobile.test.onegini.com/resources/", + @"ONGAppVersion" : @"1.0.0", + @"ONGAppBaseURL" : @"https://mobile-security-proxy.test.onegini.com", + @"ONGResourceBaseURL" : @"https://mobile-security-proxy.test.onegini.com/resources/", @"ONGRedirectURL" : @"oneginiexample://loginsuccess", }; } + (NSString *)serverPublicKey { - return @"4B8E698FEAA9F0A1E99644E77E1AB9EF5F63FBBFBA5EE52D881AADB2C0373336"; + return @"E23EDEC22396C17B204D9996295ED0045E5500B3281F0D00F242D71B5A4F3EC9"; } @end \ No newline at end of file diff --git a/example/ios/Flutter/Flutter.podspec b/example/ios/Flutter/Flutter.podspec deleted file mode 100644 index 8ce43943..00000000 --- a/example/ios/Flutter/Flutter.podspec +++ /dev/null @@ -1,18 +0,0 @@ -# -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# This is a generated file; do not edit or check into version control. -# - -Pod::Spec.new do |s| - s.name = 'Flutter' - s.version = '1.0.0' - s.summary = 'A UI toolkit for beautiful and fast apps.' - s.homepage = 'https://flutter.dev' - s.license = { :type => 'BSD' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '11.0' - # Framework linking is handled by Flutter tooling, not CocoaPods. - # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. - s.vendored_frameworks = 'path/to/nothing' -end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock deleted file mode 100644 index 97d8d58e..00000000 --- a/example/ios/Podfile.lock +++ /dev/null @@ -1,89 +0,0 @@ -PODS: - - AFNetworking (4.0.1): - - AFNetworking/NSURLSession (= 4.0.1) - - AFNetworking/Reachability (= 4.0.1) - - AFNetworking/Security (= 4.0.1) - - AFNetworking/Serialization (= 4.0.1) - - AFNetworking/UIKit (= 4.0.1) - - AFNetworking/NSURLSession (4.0.1): - - AFNetworking/Reachability - - AFNetworking/Security - - AFNetworking/Serialization - - AFNetworking/Reachability (4.0.1) - - AFNetworking/Security (4.0.1) - - AFNetworking/Serialization (4.0.1) - - AFNetworking/UIKit (4.0.1): - - AFNetworking/NSURLSession - - Flutter (1.0.0) - - fluttertoast (0.0.2): - - Flutter - - Toast - - MTBBarcodeScanner (5.0.11) - - onegini (1.2.1): - - Flutter - - OneginiSDKiOS (~> 12.2.2) - - OneginiSDKiOS (12.2.2): - - AFNetworking (~> 4.0.1) - - Typhoon (~> 4.0.8) - - qr_code_scanner (0.2.0): - - Flutter - - MTBBarcodeScanner - - SwiftLint (0.51.0) - - Toast (4.0.0) - - Typhoon (4.0.9): - - Typhoon/DeallocNotifier (= 4.0.9) - - Typhoon/IntrospectionUtils (= 4.0.9) - - Typhoon/no-arc (= 4.0.9) - - Typhoon/DeallocNotifier (4.0.9) - - Typhoon/IntrospectionUtils (4.0.9) - - Typhoon/no-arc (4.0.9): - - Typhoon/IntrospectionUtils - - url_launcher_ios (0.0.1): - - Flutter - -DEPENDENCIES: - - Flutter (from `Flutter`) - - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - - onegini (from `.symlinks/plugins/onegini/ios`) - - qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`) - - SwiftLint - - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - -SPEC REPOS: - https://github.com/CocoaPods/Specs.git: - - AFNetworking - - MTBBarcodeScanner - - SwiftLint - - Toast - - Typhoon - https://repo.onewelcome.com/artifactory/api/pods/cocoapods-public: - - OneginiSDKiOS - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - fluttertoast: - :path: ".symlinks/plugins/fluttertoast/ios" - onegini: - :path: ".symlinks/plugins/onegini/ios" - qr_code_scanner: - :path: ".symlinks/plugins/qr_code_scanner/ios" - url_launcher_ios: - :path: ".symlinks/plugins/url_launcher_ios/ios" - -SPEC CHECKSUMS: - AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - onegini: 28cf385b65961a518044f8ad5d0657193c4c3312 - OneginiSDKiOS: 33f5b66aacefbb54825ecde2d6b3e1fb22117dbd - qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e - SwiftLint: 1b7561918a19e23bfed960e40759086e70f4dba5 - Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 - Typhoon: 1973c93ecfb3edb963d78b10e715bc2911475bd2 - url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 - -PODFILE CHECKSUM: e49c186fd5db1b7547d2a80e7096f4e0713e90f9 - -COCOAPODS: 1.11.3 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 6b9ecbf2..e8b5841d 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -423,6 +423,7 @@ files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( diff --git a/example/lib/main.dart b/example/lib/main.dart index 6eccea43..ebf34aa0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,7 +3,7 @@ import 'package:flutter/services.dart'; import 'package:onegini/onegini.dart'; import 'package:onegini/onegini.gen.dart'; import 'package:onegini_example/components/display_toast.dart'; -import 'package:onegini_example/screens/login_screen.dart'; +import 'package:onegini_example/screens/auth_screen.dart'; final RouteObserver routeObserver = RouteObserver(); @@ -72,7 +72,7 @@ class _BodyWidgetState extends State { Navigator.pushReplacement( context, - MaterialPageRoute(builder: (context) => LoginScreen()), + MaterialPageRoute(builder: (context) => AuthScreen()), ); } diff --git a/example/lib/screens/login_screen.dart b/example/lib/screens/auth_screen.dart similarity index 82% rename from example/lib/screens/login_screen.dart rename to example/lib/screens/auth_screen.dart index cbe4729c..e254053a 100644 --- a/example/lib/screens/login_screen.dart +++ b/example/lib/screens/auth_screen.dart @@ -15,17 +15,15 @@ import 'package:collection/collection.dart'; import '../components/display_toast.dart'; -class LoginScreen extends StatefulWidget { +class AuthScreen extends StatefulWidget { @override - _LoginScreenState createState() => _LoginScreenState(); + _AuthScreenState createState() => _AuthScreenState(); } -class _LoginScreenState extends State { +class _AuthScreenState extends State { bool isLoading = false; List>? registrationSubscriptions; List>? authenticationSubscriptions; - List userProfiles = []; - String? selectedProfileId; @override initState() { @@ -35,20 +33,18 @@ class _LoginScreenState extends State { this.authenticationSubscriptions = OWBroadcastHelper.initAuthenticationSubscriptions(context); super.initState(); - getUserProfiles(); } @override void dispose() { OWBroadcastHelper.stopListening(registrationSubscriptions); OWBroadcastHelper.stopListening(authenticationSubscriptions); - super.dispose(); } - openWeb() async { + _openWeb() async { /// Start registration - setState(() => {isLoading = true}); + setState(() => isLoading = true); try { var registrationResponse = await Onegini.instance.userClient.registerUser( @@ -71,8 +67,8 @@ class _LoginScreenState extends State { } } - registrationWithIdentityProvider(String identityProviderId) async { - setState(() => {isLoading = true}); + _registraterWithIdentityProvider(String identityProviderId) async { + setState(() => isLoading = true); try { var registrationResponse = await Onegini.instance.userClient.registerUser( identityProviderId, @@ -94,25 +90,7 @@ class _LoginScreenState extends State { } } - authenticate(String profileId, OWAuthenticatorType? authenticatorType) async { - try { - var registrationResponse = await Onegini.instance.userClient - .authenticateUser(profileId, authenticatorType); - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute( - builder: (context) => UserScreen( - userProfileId: registrationResponse.userProfile.profileId, - )), - (Route route) => false); - } catch (error) { - if (error is PlatformException) { - showFlutterToast(error.message); - } - } - } - - cancelRegistration() async { + _cancelRegistration() async { setState(() => isLoading = false); try { await Future.any([ @@ -124,53 +102,6 @@ class _LoginScreenState extends State { } } - Future> getUserProfiles() async { - try { - final profiles = await Onegini.instance.userClient.getUserProfiles(); - setState(() { - userProfiles = profiles; - if (selectedProfileId == null) { - selectedProfileId = profiles.firstOrNull?.profileId; - } - }); - return profiles; - } catch (err) { - print("caught error in getUserProfiles: $err"); - return []; - } - } - - Future getImplicitUserDetails(String profileId) async { - try { - await Onegini.instance.userClient - .authenticateUserImplicitly(profileId, ["read"]); - var response = await Onegini.instance.resourcesMethods.requestResource( - ResourceRequestType.implicit, - RequestDetails( - path: "user-id-decorated", method: HttpRequestMethod.get)); - - var res = json.decode(response.body); - - return res["decorated_user_id"]; - } catch (err) { - print("Caught error: $err"); - return "Error occured check logs"; - } - } - - Widget _buildImplicitUserData(String profileId) { - return FutureBuilder( - future: getImplicitUserDetails(profileId), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Text("${snapshot.data}"); - } else if (snapshot.hasError) { - return Text("Error getting implicit details."); - } - return CircularProgressIndicator(); - }); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -195,7 +126,7 @@ class _LoginScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox(height: 20), - _buildLoginWidget(), + LoginSection(), SizedBox(height: 20), _buildRegisterWidget(), ], @@ -204,60 +135,6 @@ class _LoginScreenState extends State { ); } - Widget _buildLoginWidget() { - final profileId = selectedProfileId; - return (userProfiles.length > 0 && profileId != null) - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "──── Login ────", - style: TextStyle(fontSize: 30), - textAlign: TextAlign.center, - ), - _buildSelectUserProfile(userProfiles), - _buildImplicitUserData(profileId), - ElevatedButton( - onPressed: () { - authenticate(profileId, null); - }, - child: Text('Preferred authenticator'), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () { - authenticate(profileId, OWAuthenticatorType.pin); - }, - child: Text('Pin'), - ), - SizedBox(height: 10, width: 10), - ElevatedButton( - onPressed: () { - authenticate(profileId, OWAuthenticatorType.biometric); - }, - child: Text('Biometrics'), - ), - ], - ), - ]) - : SizedBox.shrink(); - } - - DropdownButton _buildSelectUserProfile(List profiles) { - return DropdownButton( - value: selectedProfileId, - items: profiles - .map((e) => - DropdownMenuItem(value: e.profileId, child: Text(e.profileId))) - .toList(), - onChanged: (profileId) => { - setState(() => {selectedProfileId = profileId}) - }); - } - Column _buildRegisterWidget() { return Column( children: [ @@ -268,7 +145,7 @@ class _LoginScreenState extends State { SizedBox(height: 20), ElevatedButton( onPressed: () { - openWeb(); + _openWeb(); }, child: Text('Run WEB'), ), @@ -291,7 +168,7 @@ class _LoginScreenState extends State { ), ), onSelected: (value) { - registrationWithIdentityProvider(value); + _registraterWithIdentityProvider(value); }, itemBuilder: (context) { return identityProviders @@ -317,7 +194,7 @@ class _LoginScreenState extends State { SizedBox(height: 20), ElevatedButton( onPressed: () { - cancelRegistration(); + _cancelRegistration(); }, child: Text('Cancel'), ), @@ -325,3 +202,141 @@ class _LoginScreenState extends State { ); } } + +class LoginSection extends StatefulWidget { + @override + _LoginSectionState createState() => _LoginSectionState(); +} + +class _LoginSectionState extends State { + List userProfiles = []; + String? selectedProfileId; + + @override + initState() { + super.initState(); + _fetchUserProfiles(); + } + + @override + Widget build(BuildContext context) { + final _selectedProfileId = selectedProfileId; + return (userProfiles.length > 0 && _selectedProfileId != null) + ? Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "──── Login ────", + style: TextStyle(fontSize: 30), + textAlign: TextAlign.center, + ), + _buildSelectUserProfile(userProfiles), + _buildImplicitUserData(_selectedProfileId), + ElevatedButton( + onPressed: () { + _authenticate(_selectedProfileId, null); + }, + child: Text('Preferred authenticator'), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + _authenticate( + _selectedProfileId, OWAuthenticatorType.pin); + }, + child: Text('Pin'), + ), + SizedBox(height: 10, width: 10), + ElevatedButton( + onPressed: () { + _authenticate( + _selectedProfileId, OWAuthenticatorType.biometric); + }, + child: Text('Biometrics'), + ), + ], + ), + ]) + : SizedBox.shrink(); + } + + DropdownButton _buildSelectUserProfile(List profiles) { + return DropdownButton( + value: selectedProfileId, + items: profiles + .map((e) => + DropdownMenuItem(value: e.profileId, child: Text(e.profileId))) + .toList(), + onChanged: (profileId) => + {setState(() => selectedProfileId = profileId)}); + } + + Future> _fetchUserProfiles() async { + try { + final profiles = await Onegini.instance.userClient.getUserProfiles(); + setState(() { + userProfiles = profiles; + selectedProfileId = + selectedProfileId ?? profiles.firstOrNull?.profileId; + }); + return profiles; + } catch (err) { + print("caught error in getUserProfiles: $err"); + return []; + } + } + + Widget _buildImplicitUserData(final String profileId) { + return FutureBuilder( + future: _getImplicitUserDetails(profileId), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + return Text("${snapshot.data}"); + } else if (snapshot.hasError) { + return Text("Error getting implicit details."); + } + return CircularProgressIndicator(); + }); + } + + Future _getImplicitUserDetails(final String profileId) async { + try { + await Onegini.instance.userClient + .authenticateUserImplicitly(profileId, ["read"]); + var response = await Onegini.instance.resourcesMethods.requestResource( + ResourceRequestType.implicit, + RequestDetails( + path: "user-id-decorated", method: HttpRequestMethod.get)); + + var res = json.decode(response.body); + + return res["decorated_user_id"]; + } catch (err) { + print("Caught error: $err"); + return "Error occured check logs"; + } + } + + _authenticate( + final String profileId, OWAuthenticatorType? authenticatorType) async { + try { + var registrationResponse = await Onegini.instance.userClient + .authenticateUser(profileId, authenticatorType); + Navigator.pushAndRemoveUntil( + context, + MaterialPageRoute( + builder: (context) => UserScreen( + userProfileId: registrationResponse.userProfile.profileId, + )), + (Route route) => false); + } catch (error) { + if (error is PlatformException) { + showFlutterToast(error.message); + } + } + } +} diff --git a/example/lib/screens/otp_screen.dart b/example/lib/screens/otp_screen.dart index 725e9b0e..f7b6573f 100644 --- a/example/lib/screens/otp_screen.dart +++ b/example/lib/screens/otp_screen.dart @@ -3,7 +3,7 @@ import 'package:flutter/services.dart'; import 'package:onegini/callbacks/onegini_custom_registration_callback.dart'; import 'package:onegini_example/components/display_toast.dart'; -import 'login_screen.dart'; +import 'auth_screen.dart'; class OtpScreen extends StatefulWidget { final String password; @@ -42,7 +42,7 @@ class _OtpScreenState extends State { }); Navigator.pushReplacement( context, - MaterialPageRoute(builder: (context) => LoginScreen()), + MaterialPageRoute(builder: (context) => AuthScreen()), ); } diff --git a/example/lib/screens/pin_screen.dart b/example/lib/screens/pin_screen.dart index 26aa471e..9166ef20 100644 --- a/example/lib/screens/pin_screen.dart +++ b/example/lib/screens/pin_screen.dart @@ -59,7 +59,7 @@ class _PinScreenState extends State { } submit() { - setState(() => {isLoading = true}); + setState(() => isLoading = true); String pin = ""; pinCode.forEach((element) { pin += element; @@ -68,7 +68,7 @@ class _PinScreenState extends State { .acceptAuthenticationRequest(pin) .catchError((error) { if (error is PlatformException) { - setState(() => {isLoading = false}); + setState(() => isLoading = false); showFlutterToast(error.message); } }); diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index 4a2f15c2..2312f874 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -18,7 +18,7 @@ import 'package:onegini/onegini.gen.dart'; // ignore: import_of_legacy_library_into_null_safe import '../main.dart'; // ignore: import_of_legacy_library_into_null_safe -import 'login_screen.dart'; +import 'auth_screen.dart'; class UserScreen extends StatefulWidget { final String userProfileId; @@ -113,7 +113,7 @@ class _UserScreenState extends State with RouteAware { }); Navigator.pushReplacement( context, - MaterialPageRoute(builder: (_) => LoginScreen()), + MaterialPageRoute(builder: (_) => AuthScreen()), ); } @@ -127,7 +127,7 @@ class _UserScreenState extends State with RouteAware { }); Navigator.pushReplacement( context, - MaterialPageRoute(builder: (_) => LoginScreen()), + MaterialPageRoute(builder: (_) => AuthScreen()), ); } @@ -144,7 +144,7 @@ class _UserScreenState extends State with RouteAware { error.code == PlatformErrorCodes.userNotAuthenticated) { Navigator.pushReplacement( context, - MaterialPageRoute(builder: (_) => LoginScreen()), + MaterialPageRoute(builder: (_) => AuthScreen()), ); } } diff --git a/lib/onegini.dart b/lib/onegini.dart index 27dfc597..dc284442 100644 --- a/lib/onegini.dart +++ b/lib/onegini.dart @@ -11,7 +11,7 @@ import 'package:onegini/onegini.gen.dart'; class Onegini { // UserClientApi is the flutter to native api created by the Pigeon package, see /pigeons/README.md /// User client methods. - final UserClientApi api = UserClientApi(); + final UserClientApi _api = UserClientApi(); late final UserClient userClient; @@ -24,7 +24,7 @@ class Onegini { Finalizer((owEventStreamController) => owEventStreamController.close()); Onegini._internal() { - userClient = UserClient(api); + userClient = UserClient(_api); } static final Onegini instance = Onegini._internal(); @@ -51,7 +51,7 @@ class Onegini { List? additionalResourceUrls, }) async { NativeCallFlutterApi.setup(OneginiEventListener(owEventStreamController)); - await api.startApplication( + await _api.startApplication( securityControllerClassName, configModelClassName, customIdentityProviderConfigs, diff --git a/pubspec.yaml b/pubspec.yaml index 79ec54e5..73d9e19d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: onegini description: The Onegini Flutter Plugin is a plugin that allows you to utilize the Onegini Mobile SDKs in your Flutter applications. -version: 3.0.0 +version: 3.0.1 homepage: https://www.onegini.com environment: - sdk: ">=2.12.0 <4.0.0" + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.12.0" dependencies: