From 03d3b0b5f6210843bf1711473c4093faac3c8bb4 Mon Sep 17 00:00:00 2001 From: Sergio Fierro Date: Fri, 16 Feb 2024 14:21:03 -0500 Subject: [PATCH 1/9] Android SDK size report --- .circleci/config.yml | 39 ++++++ build.gradle.kts | 114 +++++++++--------- .../dangerfile_android_sdk_size_report | 3 + gradle/libs.versions.toml | 3 + shared/build.gradle.kts | 33 +++++ 5 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 dangerfiles/dangerfile_android_sdk_size_report diff --git a/.circleci/config.yml b/.circleci/config.yml index 232d659c..a39a3d94 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -63,6 +63,17 @@ commands: name: Danger check command: bundle exec danger <> --verbose --remove-previous-comments + move_directory: + parameters: + from: + description: directory to move + type: string + to: + description: destination directory + type: string + steps: + - run: cp -R <> <> + jobs: assemble: executor: android-executor @@ -155,6 +166,31 @@ jobs: - store_artifacts: path: /Users/distiller/test-results/ + android-sdk-size-report: + executor: android-executor + + steps: + - checkout + - android/restore-build-cache + - android/restore-gradle-cache + - ruby/install-deps + - run: + name: Android SDK size report + command: ./gradlew generateSizeReport + - store_artifacts: + path: "shared/build/outputs/sizeReport" + destination: sizeReport + - run: mkdir -p builds + - move_directory: + from: shared/build/outputs/sizeReport/ + to: builds + - danger-check: + danger_params: --danger_id=android_sdk_report --dangerfile=dangerfiles/dangerfile_android_sdk_size_report + - persist_to_workspace: + root: *workspace + paths: + - builds + ios-generate-framework: executor: mac-os-executor @@ -197,6 +233,9 @@ workflows: - lint-check: requires: - assemble + - android-sdk-size-report: + requires: + - assemble - detekt-check: requires: - assemble diff --git a/build.gradle.kts b/build.gradle.kts index 916a5180..2d305420 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,69 +3,75 @@ import io.gitlab.arturbosch.detekt.DetektPlugin import org.jlleitschuh.gradle.ktlint.KtlintPlugin import org.jlleitschuh.gradle.ktlint.reporter.ReporterType +buildscript { + dependencies { + classpath(libs.apkscale) + } +} + plugins { - // trick: for the same plugin versions in all sub-modules - alias(libs.plugins.androidApplication).apply(false) - alias(libs.plugins.androidLibrary).apply(false) - alias(libs.plugins.kotlinAndroid).apply(false) - alias(libs.plugins.kotlinMultiplatform).apply(false) - alias(libs.plugins.hilt).apply(false) - alias(libs.plugins.kotlinSerialization) - alias(libs.plugins.jvm) - alias(libs.plugins.kover).apply(false) - alias(libs.plugins.ktlint) - alias(libs.plugins.detekt) + // trick: for the same plugin versions in all sub-modules + alias(libs.plugins.androidApplication).apply(false) + alias(libs.plugins.androidLibrary).apply(false) + alias(libs.plugins.kotlinAndroid).apply(false) + alias(libs.plugins.kotlinMultiplatform).apply(false) + alias(libs.plugins.hilt).apply(false) + alias(libs.plugins.kotlinSerialization) + alias(libs.plugins.jvm) + alias(libs.plugins.kover).apply(false) + alias(libs.plugins.ktlint) + alias(libs.plugins.detekt) } allprojects { - apply() - ktlint { - version = "1.1.0" - verbose.set(true) - debug.set(true) - outputToConsole.set(true) - ignoreFailures.set(true) - reporters { - reporter(ReporterType.JSON) - } + apply() + ktlint { + version = "1.1.0" + verbose.set(true) + debug.set(true) + outputToConsole.set(true) + ignoreFailures.set(true) + reporters { + reporter(ReporterType.JSON) } + } - tasks.withType { - reportsOutputDirectory.set( - project.layout.buildDirectory.dir("$buildDir/reports/ktlint"), - ) - } + tasks.withType { + reportsOutputDirectory.set( + project.layout.buildDirectory.dir("$buildDir/reports/ktlint"), + ) + } - apply() - detekt { - ignoreFailures = true - parallel = true // can lead to speedups in larger projects - buildUponDefaultConfig = true // preconfigure defaults - allRules = false // activate all available (even unstable) rules. - config.setFrom("$rootDir/config/detekt.yml") // point to your custom config defining rules to run, overwriting default behavior - source.setFrom( - "src/main/java", - "src/main/kotlin", - "src/androidMain/kotlin", - "src/androidUnitTest/kotlin", - "src/androidInstrumentedTest/kotlin", - "src/commonTest/kotlin", - "src/commonMain/kotlin", - "src/iosMain/kotlin", - "src/iosTest/kotlin", - ) - } + apply() + detekt { + ignoreFailures = true + parallel = true // can lead to speedups in larger projects + buildUponDefaultConfig = true // preconfigure defaults + allRules = false // activate all available (even unstable) rules. + config.setFrom("$rootDir/config/detekt.yml") // point to your custom config defining rules to run, overwriting default behavior + source.setFrom( + "src/main/java", + "src/main/kotlin", + "src/androidMain/kotlin", + "src/androidUnitTest/kotlin", + "src/androidInstrumentedTest/kotlin", + "src/commonTest/kotlin", + "src/commonMain/kotlin", + "src/iosMain/kotlin", + "src/iosTest/kotlin", + ) + } - val reportMerge by tasks.registering(io.gitlab.arturbosch.detekt.report.ReportMergeTask::class) { - output.set(rootProject.layout.buildDirectory.file("reports/detekt/detekt.xml")) + val reportMerge by tasks.registering(io.gitlab.arturbosch.detekt.report.ReportMergeTask::class) { + output.set(rootProject.layout.buildDirectory.file("reports/detekt/detekt.xml")) + } + subprojects { + tasks.withType().configureEach { + finalizedBy(reportMerge) } - subprojects { - tasks.withType().configureEach { - finalizedBy(reportMerge) - } - reportMerge { - input.from(tasks.withType().map { it.xmlReportFile }) // or .sarifReportFile - } + reportMerge { + input.from(tasks.withType().map { it.xmlReportFile }) // or .sarifReportFile } + } } diff --git a/dangerfiles/dangerfile_android_sdk_size_report b/dangerfiles/dangerfile_android_sdk_size_report new file mode 100644 index 00000000..4bf9e623 --- /dev/null +++ b/dangerfiles/dangerfile_android_sdk_size_report @@ -0,0 +1,3 @@ +# Android SDK size report +file = File.read("shared/build/outputs/sizeReport/AndroidSDKSizeReport.txt") +warn file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 940e0b5d..035e4f39 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] agp = "8.2.0" +apkscale = "0.1.6" constraintlayout = "2.1.4" constraintlayoutCompose = "1.0.1" credentials = "1.2.0" @@ -34,6 +35,7 @@ androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayo androidx-constraintlayout-compose = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "constraintlayoutCompose" } androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" } androidx-runner = { module = "androidx.test:runner", version.ref = "runner" } +apkscale = { module = "com.twilio:apkscale", version.ref = "apkscale" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -59,6 +61,7 @@ truth = { module = "com.google.truth:truth", version.ref = "truth" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } +apkscale = { id = "com.twilio.apkscale", version.ref = "apkscale" } hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 84193247..235711c8 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -3,6 +3,7 @@ plugins { alias(libs.plugins.androidLibrary) alias(libs.plugins.kotlinSerialization) alias(libs.plugins.kover) + id("com.twilio.apkscale") id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3" id("co.touchlab.skie") version "0.6.1" } @@ -88,6 +89,7 @@ android { compileSdk = 34 defaultConfig { minSdk = 24 + targetSdkVersion(34) // Don't remove this, apkscale plugin needs it testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { @@ -102,6 +104,37 @@ android { } } + apkscale { + abis = setOf("x86", "x86_64", "armeabi-v7a", "arm64-v8a") + } + + task("generateSizeReport") { + dependsOn("assembleRelease", "measureSize") + description = "Calculate Passkeys Android SDK Size Impact" + group = "Reporting" + + doLast { + var sizeReport = + "### Size impact\n" + + "\n" + + "| ABI | APK Size Impact |\n" + + "| --------------- | --------------- |\n" + val apkscaleOutputFile = file("$buildDir/apkscale/build/outputs/reports/apkscale.json") + val jsonSlurper = groovy.json.JsonSlurper() + val apkscaleOutput = jsonSlurper.parseText(apkscaleOutputFile.readText()) as List<*> + val releaseOutput = apkscaleOutput[0] as Map<*, *> + val sizes = releaseOutput["size"] as Map + sizes.forEach { (arch, sizeImpact) -> + sizeReport += "| ${arch.padEnd(16)}| ${sizeImpact.padEnd(16)}|\n" + } + val sizeReportDir = "$buildDir/outputs/sizeReport" + mkdir(sizeReportDir) + val targetFile = file("$sizeReportDir/AndroidSDKSizeReport.txt") + targetFile.createNewFile() + targetFile.writeText(sizeReport) + } + } + dependencies { implementation(libs.androidx.credentials) implementation(libs.androidx.credentials.auth) From 4d6a9cf640d1baf04205a30bd355e8c9f2bbdceb Mon Sep 17 00:00:00 2001 From: Felipe Erazo Date: Tue, 20 Feb 2024 08:50:34 -0500 Subject: [PATCH 2/9] rename AndroidApp->androidApp. Complete and solve syntax errors in readme file --- README.md | 25 +++++++++++++----- {AndroidApp => androidApp}/build.gradle.kts | 0 .../detekt-baseline.xml | 0 .../src/main/AndroidManifest.xml | 0 .../twilio/passkeys/android/LoginViewModel.kt | 0 .../twilio/passkeys/android/MainActivity.kt | 0 .../com/twilio/passkeys/android/PasskeyApp.kt | 0 .../passkeys/android/api/AuthenticateApi.kt | 0 .../passkeys/android/api/RegistrationApi.kt | 0 .../android/di/TwilioPasskeyModule.kt | 0 .../model/AuthenticateVerificationResponse.kt | 0 .../model/RegistrationVerificationResponse.kt | 0 .../twilio/passkeys/android/pages/HomePage.kt | 0 .../passkeys/android/pages/LoginPage.kt | 0 .../repository/AuthenticateRepository.kt | 0 .../android/repository/CreateRepository.kt | 0 .../com/twilio/passkeys/android/ui/Color.kt | 0 .../passkeys/android/ui/MyApplicationTheme.kt | 0 .../src/main/res/drawable-hdpi/owl_image.png | Bin .../src/main/res/drawable-mdpi/owl_image.png | Bin .../src/main/res/drawable-xhdpi/owl_image.png | Bin .../main/res/drawable-xxhdpi/owl_image.png | Bin .../src/main/res/drawable/copy.xml | 0 .../src/main/res/drawable/credit_card.xml | 0 .../src/main/res/drawable/dollar.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 .../res/drawable/ic_launcher_foreground.xml | 0 .../src/main/res/drawable/menu.xml | 0 .../src/main/res/drawable/owl.xml | 0 .../src/main/res/drawable/owl_inverted.xml | 0 .../src/main/res/drawable/twilio.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 .../res/mipmap-hdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../res/mipmap-mdpi/ic_launcher_round.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../res/mipmap-xhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin .../res/values/ic_launcher_background.xml | 0 .../src/main/res/values/strings.xml | 0 .../src/main/res/values/styles.xml | 0 46 files changed, 19 insertions(+), 6 deletions(-) rename {AndroidApp => androidApp}/build.gradle.kts (100%) rename {AndroidApp => androidApp}/detekt-baseline.xml (100%) rename {AndroidApp => androidApp}/src/main/AndroidManifest.xml (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/MainActivity.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/ui/Color.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt (100%) rename {AndroidApp => androidApp}/src/main/res/drawable-hdpi/owl_image.png (100%) rename {AndroidApp => androidApp}/src/main/res/drawable-mdpi/owl_image.png (100%) rename {AndroidApp => androidApp}/src/main/res/drawable-xhdpi/owl_image.png (100%) rename {AndroidApp => androidApp}/src/main/res/drawable-xxhdpi/owl_image.png (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/copy.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/credit_card.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/dollar.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/ic_launcher_background.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/ic_launcher_foreground.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/menu.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/owl.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/owl_inverted.xml (100%) rename {AndroidApp => androidApp}/src/main/res/drawable/twilio.xml (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-hdpi/ic_launcher_round.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-mdpi/ic_launcher_round.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xhdpi/ic_launcher_round.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xxhdpi/ic_launcher_round.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {AndroidApp => androidApp}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png (100%) rename {AndroidApp => androidApp}/src/main/res/values/ic_launcher_background.xml (100%) rename {AndroidApp => androidApp}/src/main/res/values/strings.xml (100%) rename {AndroidApp => androidApp}/src/main/res/values/styles.xml (100%) diff --git a/README.md b/README.md index 8eabb118..90ede098 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * [Requirements](#requirements) * [Installation](#installation) * [Quickstart](#quickstart) -* [Running Sample app](#building-and-running-sample-app) +* [Building and Running Sample App](#building-and-running-sample-app) * [Project Structure](#project-structure) * [Code Structure](#code-structure) * [Useful Gradle Tasks](#useful-gradle-tasks) @@ -33,7 +33,7 @@ Twilio Passkeys SDK enables developers to easily add Passkeys into their existin ## Installation ### Installation Android -1. Download the .aar file from release page. +1. Download the .aar file from the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). 2. Create a folder `libs` in the module directory. 3. Copy/move the .aar file in `libs` folder. 4. Add the implementation statement in dependencies: @@ -48,7 +48,14 @@ val twilioPasskey = TwilioPasskey(context) ### Installation iOS -1. (WIP) +1. Download the XCFramework form the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). +2. Create a Framework folder or use any name of your preference. +3. Copy/Move the XCFramework into the folder created at the previous step. +4. On your Project Configurations > General > Frameworks, Libraries, and Embedded Content section, drag & drop the XCFramework. +5. Import TwilioPasskeys in the files you will make use of it: +``` +let twilioPasskey = TwilioPasskey() +``` ## Quickstart @@ -111,7 +118,7 @@ if let success = response as? AuthenticatePasskeyResult.Success { ### Create Challenge Payload -The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for register a user, it uses the JSON schema: +The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for registering a user, it uses the JSON schema: ``` {"rp":{"id":"your_backend","name":"PasskeySample"},"user":{"id":"WUV...5Ng","name":"1234567890","displayName":"1234567890"},"challenge":"WUY...jZQ","pubKeyCredParams":[{"type":"public-key","alg":-7}],"timeout":600000,"excludeCredentials":[],"authenticatorSelection":{"authenticatorAttachment":"platform","requireResidentKey":false,"residentKey":"preferred","userVerification":"preferred"},"attestation":"none"} ``` @@ -131,11 +138,15 @@ The challenge payload for authenticating a user is a JSON with the schema: 2. Open the project in IntelliJ IDEA or Android Studio. 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt#L42). 4. Build and run the Android app from the `androidApp` module. -5. Associate the app sha256 to the backend by running `./gradlew signingreport` and adding the sha-256 value in the `sha256_cert_fingerprints` array of the file `well-known/assetlinks.json`. -6. Add the origin following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). **Note**: To start sign up/in flows, the Android device must have a valid Google account to store and fetch passkeys. +**Backend-side configuration for Android Sample App**
+ +1. Make sure you already [added support for digital asset links](https://developer.android.com/training/sign-in/passkeys#add-support-dal) in your backend by checking whether an entry with the build sha256 value exists. You can generate a sha256 by running `./gradlew signingreport`. +2. Add the origin if you have not added it yet, following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). + + #### iOS 1. Clone this repository. @@ -143,6 +154,8 @@ The challenge payload for authenticating a user is a JSON with the schema: 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/Core/AuthenticationManager.swift#L22) and [Entitlements](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/iosApp.entitlements#L7) 4. Build and run the iOS app from the `iosApp` module. +**Note**: To start sign up/in flows, the iPhone must have a valid iCloud account to store and fetch passkeys. + ## Project Structure - `shared`: This module contains the shared code, including business logic, data models, and utility functions. diff --git a/AndroidApp/build.gradle.kts b/androidApp/build.gradle.kts similarity index 100% rename from AndroidApp/build.gradle.kts rename to androidApp/build.gradle.kts diff --git a/AndroidApp/detekt-baseline.xml b/androidApp/detekt-baseline.xml similarity index 100% rename from AndroidApp/detekt-baseline.xml rename to androidApp/detekt-baseline.xml diff --git a/AndroidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml similarity index 100% rename from AndroidApp/src/main/AndroidManifest.xml rename to androidApp/src/main/AndroidManifest.xml diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt b/androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt b/androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt b/androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt b/androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt b/androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt b/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt b/androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt b/androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt b/androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt b/androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt b/androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt b/androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt diff --git a/AndroidApp/src/main/res/drawable-hdpi/owl_image.png b/androidApp/src/main/res/drawable-hdpi/owl_image.png similarity index 100% rename from AndroidApp/src/main/res/drawable-hdpi/owl_image.png rename to androidApp/src/main/res/drawable-hdpi/owl_image.png diff --git a/AndroidApp/src/main/res/drawable-mdpi/owl_image.png b/androidApp/src/main/res/drawable-mdpi/owl_image.png similarity index 100% rename from AndroidApp/src/main/res/drawable-mdpi/owl_image.png rename to androidApp/src/main/res/drawable-mdpi/owl_image.png diff --git a/AndroidApp/src/main/res/drawable-xhdpi/owl_image.png b/androidApp/src/main/res/drawable-xhdpi/owl_image.png similarity index 100% rename from AndroidApp/src/main/res/drawable-xhdpi/owl_image.png rename to androidApp/src/main/res/drawable-xhdpi/owl_image.png diff --git a/AndroidApp/src/main/res/drawable-xxhdpi/owl_image.png b/androidApp/src/main/res/drawable-xxhdpi/owl_image.png similarity index 100% rename from AndroidApp/src/main/res/drawable-xxhdpi/owl_image.png rename to androidApp/src/main/res/drawable-xxhdpi/owl_image.png diff --git a/AndroidApp/src/main/res/drawable/copy.xml b/androidApp/src/main/res/drawable/copy.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/copy.xml rename to androidApp/src/main/res/drawable/copy.xml diff --git a/AndroidApp/src/main/res/drawable/credit_card.xml b/androidApp/src/main/res/drawable/credit_card.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/credit_card.xml rename to androidApp/src/main/res/drawable/credit_card.xml diff --git a/AndroidApp/src/main/res/drawable/dollar.xml b/androidApp/src/main/res/drawable/dollar.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/dollar.xml rename to androidApp/src/main/res/drawable/dollar.xml diff --git a/AndroidApp/src/main/res/drawable/ic_launcher_background.xml b/androidApp/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/ic_launcher_background.xml rename to androidApp/src/main/res/drawable/ic_launcher_background.xml diff --git a/AndroidApp/src/main/res/drawable/ic_launcher_foreground.xml b/androidApp/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/ic_launcher_foreground.xml rename to androidApp/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/AndroidApp/src/main/res/drawable/menu.xml b/androidApp/src/main/res/drawable/menu.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/menu.xml rename to androidApp/src/main/res/drawable/menu.xml diff --git a/AndroidApp/src/main/res/drawable/owl.xml b/androidApp/src/main/res/drawable/owl.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/owl.xml rename to androidApp/src/main/res/drawable/owl.xml diff --git a/AndroidApp/src/main/res/drawable/owl_inverted.xml b/androidApp/src/main/res/drawable/owl_inverted.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/owl_inverted.xml rename to androidApp/src/main/res/drawable/owl_inverted.xml diff --git a/AndroidApp/src/main/res/drawable/twilio.xml b/androidApp/src/main/res/drawable/twilio.xml similarity index 100% rename from AndroidApp/src/main/res/drawable/twilio.xml rename to androidApp/src/main/res/drawable/twilio.xml diff --git a/AndroidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from AndroidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/AndroidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from AndroidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/AndroidApp/src/main/res/mipmap-hdpi/ic_launcher.png b/androidApp/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-hdpi/ic_launcher.png rename to androidApp/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/AndroidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png b/androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png rename to androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.png diff --git a/AndroidApp/src/main/res/mipmap-mdpi/ic_launcher.png b/androidApp/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-mdpi/ic_launcher.png rename to androidApp/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/AndroidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png b/androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png rename to androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.png diff --git a/AndroidApp/src/main/res/mipmap-xhdpi/ic_launcher.png b/androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xhdpi/ic_launcher.png rename to androidApp/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/AndroidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png rename to androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/AndroidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png b/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/AndroidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png rename to androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/AndroidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/AndroidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from AndroidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png rename to androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/AndroidApp/src/main/res/values/ic_launcher_background.xml b/androidApp/src/main/res/values/ic_launcher_background.xml similarity index 100% rename from AndroidApp/src/main/res/values/ic_launcher_background.xml rename to androidApp/src/main/res/values/ic_launcher_background.xml diff --git a/AndroidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml similarity index 100% rename from AndroidApp/src/main/res/values/strings.xml rename to androidApp/src/main/res/values/strings.xml diff --git a/AndroidApp/src/main/res/values/styles.xml b/androidApp/src/main/res/values/styles.xml similarity index 100% rename from AndroidApp/src/main/res/values/styles.xml rename to androidApp/src/main/res/values/styles.xml From 7171af03f3eb07da35e13edc6ed64f84a169767c Mon Sep 17 00:00:00 2001 From: Felipe Erazo Date: Tue, 20 Feb 2024 09:42:56 -0500 Subject: [PATCH 3/9] fix readme --- README.md | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 90ede098..8eabb118 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * [Requirements](#requirements) * [Installation](#installation) * [Quickstart](#quickstart) -* [Building and Running Sample App](#building-and-running-sample-app) +* [Running Sample app](#building-and-running-sample-app) * [Project Structure](#project-structure) * [Code Structure](#code-structure) * [Useful Gradle Tasks](#useful-gradle-tasks) @@ -33,7 +33,7 @@ Twilio Passkeys SDK enables developers to easily add Passkeys into their existin ## Installation ### Installation Android -1. Download the .aar file from the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). +1. Download the .aar file from release page. 2. Create a folder `libs` in the module directory. 3. Copy/move the .aar file in `libs` folder. 4. Add the implementation statement in dependencies: @@ -48,14 +48,7 @@ val twilioPasskey = TwilioPasskey(context) ### Installation iOS -1. Download the XCFramework form the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). -2. Create a Framework folder or use any name of your preference. -3. Copy/Move the XCFramework into the folder created at the previous step. -4. On your Project Configurations > General > Frameworks, Libraries, and Embedded Content section, drag & drop the XCFramework. -5. Import TwilioPasskeys in the files you will make use of it: -``` -let twilioPasskey = TwilioPasskey() -``` +1. (WIP) ## Quickstart @@ -118,7 +111,7 @@ if let success = response as? AuthenticatePasskeyResult.Success { ### Create Challenge Payload -The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for registering a user, it uses the JSON schema: +The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for register a user, it uses the JSON schema: ``` {"rp":{"id":"your_backend","name":"PasskeySample"},"user":{"id":"WUV...5Ng","name":"1234567890","displayName":"1234567890"},"challenge":"WUY...jZQ","pubKeyCredParams":[{"type":"public-key","alg":-7}],"timeout":600000,"excludeCredentials":[],"authenticatorSelection":{"authenticatorAttachment":"platform","requireResidentKey":false,"residentKey":"preferred","userVerification":"preferred"},"attestation":"none"} ``` @@ -138,15 +131,11 @@ The challenge payload for authenticating a user is a JSON with the schema: 2. Open the project in IntelliJ IDEA or Android Studio. 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt#L42). 4. Build and run the Android app from the `androidApp` module. +5. Associate the app sha256 to the backend by running `./gradlew signingreport` and adding the sha-256 value in the `sha256_cert_fingerprints` array of the file `well-known/assetlinks.json`. +6. Add the origin following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). **Note**: To start sign up/in flows, the Android device must have a valid Google account to store and fetch passkeys. -**Backend-side configuration for Android Sample App**
- -1. Make sure you already [added support for digital asset links](https://developer.android.com/training/sign-in/passkeys#add-support-dal) in your backend by checking whether an entry with the build sha256 value exists. You can generate a sha256 by running `./gradlew signingreport`. -2. Add the origin if you have not added it yet, following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). - - #### iOS 1. Clone this repository. @@ -154,8 +143,6 @@ The challenge payload for authenticating a user is a JSON with the schema: 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/Core/AuthenticationManager.swift#L22) and [Entitlements](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/iosApp.entitlements#L7) 4. Build and run the iOS app from the `iosApp` module. -**Note**: To start sign up/in flows, the iPhone must have a valid iCloud account to store and fetch passkeys. - ## Project Structure - `shared`: This module contains the shared code, including business logic, data models, and utility functions. From 25f8caaececf2897cc5b05a0f559382314d9c3df Mon Sep 17 00:00:00 2001 From: Felipe Erazo Date: Tue, 20 Feb 2024 09:51:22 -0500 Subject: [PATCH 4/9] Revert "fix readme" This reverts commit 7171af03f3eb07da35e13edc6ed64f84a169767c. --- README.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8eabb118..90ede098 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * [Requirements](#requirements) * [Installation](#installation) * [Quickstart](#quickstart) -* [Running Sample app](#building-and-running-sample-app) +* [Building and Running Sample App](#building-and-running-sample-app) * [Project Structure](#project-structure) * [Code Structure](#code-structure) * [Useful Gradle Tasks](#useful-gradle-tasks) @@ -33,7 +33,7 @@ Twilio Passkeys SDK enables developers to easily add Passkeys into their existin ## Installation ### Installation Android -1. Download the .aar file from release page. +1. Download the .aar file from the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). 2. Create a folder `libs` in the module directory. 3. Copy/move the .aar file in `libs` folder. 4. Add the implementation statement in dependencies: @@ -48,7 +48,14 @@ val twilioPasskey = TwilioPasskey(context) ### Installation iOS -1. (WIP) +1. Download the XCFramework form the [release page](https://github.com/twilio/twilio-verify-passkeys/releases). +2. Create a Framework folder or use any name of your preference. +3. Copy/Move the XCFramework into the folder created at the previous step. +4. On your Project Configurations > General > Frameworks, Libraries, and Embedded Content section, drag & drop the XCFramework. +5. Import TwilioPasskeys in the files you will make use of it: +``` +let twilioPasskey = TwilioPasskey() +``` ## Quickstart @@ -111,7 +118,7 @@ if let success = response as? AuthenticatePasskeyResult.Success { ### Create Challenge Payload -The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for register a user, it uses the JSON schema: +The challenge payload for creating a registration is a String obtained by requesting your backend a challenge for registering a user, it uses the JSON schema: ``` {"rp":{"id":"your_backend","name":"PasskeySample"},"user":{"id":"WUV...5Ng","name":"1234567890","displayName":"1234567890"},"challenge":"WUY...jZQ","pubKeyCredParams":[{"type":"public-key","alg":-7}],"timeout":600000,"excludeCredentials":[],"authenticatorSelection":{"authenticatorAttachment":"platform","requireResidentKey":false,"residentKey":"preferred","userVerification":"preferred"},"attestation":"none"} ``` @@ -131,11 +138,15 @@ The challenge payload for authenticating a user is a JSON with the schema: 2. Open the project in IntelliJ IDEA or Android Studio. 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt#L42). 4. Build and run the Android app from the `androidApp` module. -5. Associate the app sha256 to the backend by running `./gradlew signingreport` and adding the sha-256 value in the `sha256_cert_fingerprints` array of the file `well-known/assetlinks.json`. -6. Add the origin following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). **Note**: To start sign up/in flows, the Android device must have a valid Google account to store and fetch passkeys. +**Backend-side configuration for Android Sample App**
+ +1. Make sure you already [added support for digital asset links](https://developer.android.com/training/sign-in/passkeys#add-support-dal) in your backend by checking whether an entry with the build sha256 value exists. You can generate a sha256 by running `./gradlew signingreport`. +2. Add the origin if you have not added it yet, following the [official documentation](https://developer.android.com/training/sign-in/passkeys#verify-origin). + + #### iOS 1. Clone this repository. @@ -143,6 +154,8 @@ The challenge payload for authenticating a user is a JSON with the schema: 3. Set your backend URL [BaseUrl](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/Core/AuthenticationManager.swift#L22) and [Entitlements](https://github.com/twilio/twilio-verify-passkeys/blob/main/iosApp/iosApp/iosApp.entitlements#L7) 4. Build and run the iOS app from the `iosApp` module. +**Note**: To start sign up/in flows, the iPhone must have a valid iCloud account to store and fetch passkeys. + ## Project Structure - `shared`: This module contains the shared code, including business logic, data models, and utility functions. From 15e8849e320dd524b0c013baea2db956b016b47d Mon Sep 17 00:00:00 2001 From: Felipe Erazo Date: Tue, 20 Feb 2024 15:15:52 -0500 Subject: [PATCH 5/9] mention overload of params in quickstart --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 90ede098..424d0430 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,13 @@ let twilioPasskey = TwilioPasskey() ### Create registration -Use TwilioPasskey to create a registration by calling the `create(String, AppContext)` function. Once you [create your challenge payload](#create-challenge-payload) (`challengePayload`), invoke the registration creation:
+Use the `TwilioPasskey` instance to create a registration by calling the `create(String, AppContext)` function. + +The first param is a `String` representation of a challenge payload, check how to [create your challenge payload](#create-challenge-payload) (`challengePayload`). + +The second param is an instance of a `com.twilio.passkeys.AppContext`, it is created by passing the current `Activity` instance in Android or the `UIWindow` instance in iOS. + +You can also call the `create(CreatePasskeyRequest, AppContext)` function, where `CreatePasskeyRequest` is a wrapper object of a [creation challenge payload](#create-challenge-payload) schema. **Android** ``` @@ -78,6 +84,7 @@ when(createPasskeyResult) { ``` **iOS** + ``` let response = try await twilioPasskey.create(challengePayload: challengePayload, appContext: AppContext(uiWindow: window)) if let success = response as? CreatePasskeyResult.Success { @@ -90,8 +97,16 @@ if let success = response as? CreatePasskeyResult.Success { ### Authenticate a user -**Android**
-Use TwilioPasskey to authenticate a user by calling the `authenticate(AuthenticatePasskeyRequest, AppContext)` function. The param `AuthenticatePasskeyRequest` is a wrapper [object](https://github.com/twilio/twilio-verify-passkeys/blob/55232cdc24ac80adc83c646aa302696a7039c2ad/shared/src/commonMain/kotlin/com/twilio/passkeys/models/AuthenticatePasskeyRequest.kt#L6), provided by your backend to request a Passkeys authentication, it follows the [authenticate challenge payload](#authenticate-challenge-payload) schema: +Use the `TwilioPasskey` instance to authenticate a user by calling the `authenticate(String, AppContext)` function. + +The first param is a `String` representation of an authentication request, it follows the schema of an [authentication challenge payload](#authenticate-challenge-payload). + +The second param is an instance of a `com.twilio.passkeys.AppContext`, it is created by passing the current `Activity` instance in Android or the `UIWindow` instance in iOS. + +You can also call the `authenticate(AuthenticatePasskeyRequest, AppContext)` function, which the `AuthenticatePasskeyRequest` is a wrapper object of an [authentication challenge payload](#authenticate-challenge-payload). + +**Android** + ``` val authenticatePasskeyResult = twilioPasskey.authenticate(challengePayload, AppContext(activity)) when(authenticatePasskeyResult) { @@ -105,8 +120,8 @@ when(authenticatePasskeyResult) { } ``` -**iOS**
-Use TwilioPasskey to authenticate a user by calling the `authenticate(String, AppContext)` function. The first param is a JSON that follows the [authenticate challenge payload](#authenticate-challenge-payload) schema: +**iOS** + ``` let response = try await twilioPasskey.authenticate(challengePayload: json, appContext: AppContext(uiWindow: window)) if let success = response as? AuthenticatePasskeyResult.Success { From f9c02c4c399ea9dc5bbb09ad648f0fb9fe85a316 Mon Sep 17 00:00:00 2001 From: Sergio Fierro Date: Wed, 21 Feb 2024 08:32:41 -0500 Subject: [PATCH 6/9] Rename module --- .../twilio/passkeys/android/model/AuthenticateStartResponse.kt | 0 .../twilio/passkeys/android/model/RegistrationStartResponse.kt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt (100%) rename {AndroidApp => androidApp}/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt (100%) diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt diff --git a/AndroidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt similarity index 100% rename from AndroidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt rename to androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt From 43bf774a0912eba68be119db63095331a76fdb21 Mon Sep 17 00:00:00 2001 From: Sergio Fierro Perdomo Date: Mon, 26 Feb 2024 14:08:00 -0500 Subject: [PATCH 7/9] [ACCSEC-33053] Publish internal sdk (#4) --- androidApp/build.gradle.kts | 20 +++++- androidApp/passkeys-release-key.keystore | Bin 0 -> 2808 bytes build.gradle.kts | 63 ++++++++++++++++++ gradle.properties | 3 + gradle/libs.versions.toml | 4 ++ settings.gradle.kts | 21 +++--- shared/build.gradle.kts | 81 ++++++++++++++++++++++- 7 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 androidApp/passkeys-release-key.keystore diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 167f9695..cf92b5f2 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -6,6 +6,10 @@ plugins { kotlin("kapt") } +repositories { + mavenLocal() +} + android { namespace = "com.twilio.passkeys.android" compileSdk = 34 @@ -27,9 +31,21 @@ android { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } + signingConfigs { + create("release") { + storeFile = file("passkeys-release-key.keystore") + storePassword = "twilio-verify-passkeys" + keyAlias = "twilio-verify-passkeys" + keyPassword = "twilio-verify-passkeys" + } + } buildTypes { getByName("release") { isMinifyEnabled = false + signingConfig = signingConfigs.getByName("release") + } + getByName("debug") { + signingConfig = signingConfigs.getByName("release") } } compileOptions { @@ -41,8 +57,10 @@ android { } } +val versionCode: String by extra dependencies { - implementation(projects.shared) + debugImplementation(projects.shared) + releaseImplementation("com.twilio:twilio-verify-passkeys-android:$versionCode") implementation(libs.compose.ui) implementation(libs.compose.ui.tooling.preview) implementation(libs.compose.material3) diff --git a/androidApp/passkeys-release-key.keystore b/androidApp/passkeys-release-key.keystore new file mode 100644 index 0000000000000000000000000000000000000000..15a2df01d27ee53b1da5698f0f2e7d729a7ec52b GIT binary patch literal 2808 zcma);c{CLK8pmhG%wQ}-#vU1xwaj4bBC?Aywivw42zkR0vJ})!J_&-wkH&+~kL|2^OHpvbT-5ReN+hLu2hRg#V`s-4& z6ws&Eq-&nAwbuLe`2nq;$MW%QcV_WK>A3QG@m_Pp5Ffpwx5}(i-kQdDWPJL19e5q; zjyHfC&?O!i`fw$y)xWkk58E)JWv_dW``lAGCCZC^nlF{)&B|E6B95a|zr=aDWE10c-Hq(mUWVI30i15vd@wrAG5+s-C(6wxKI3(VBbo@88dhl zJ%y`kvqRfL7nM15_;O3SZ4HIL48VfxoSc$a(c$-5H5YVq%}dkTCkC{eWC=sDPsN;A zMu~llye}WG{sAf0IkWll@I;fwE6-$tTi#>i7YLyvIgZ)7bfS0s6_wz@(L&c>5@I&x zD#Aj^AuV3$%jq5g19DXYBDk3cjoVMnp5HuGWm}WJ9VMgc+2%B()F@2CVb6KC^z65XG@fGky;q2Dt5Xcin(La1ncEEw zq7kiR3b#g_!zrRIp3^=YzgN*|oIVx0OpCjaX3Oe?z|pS3#<)s*{Asuh#eMT$yjJAE z;NMnT=w2QkM$JVy>>BuT~QLD(W+~>pfBbm>Yq+MptVm2$K z)0e+%ZPpSL68i+Lvnq=oxi`evz21Yr{k2<5w~QE07-;6);wDH^qTjXFsPq*?n^FPA zTSq0~2&svXi7ZIvUd*c84R(O>5j>M?E6 z(3^I-F;d}0sig{>NC~Pjh!t*2?GTGZDm`CvZoNAUIL#b3#b+u`8K%E7v&&peJf4E* z;d5%&ugLHP6D@K$;bAmk{p!jRdts)(rIv8nOPDsZL7mV(AhtX6wvW2yRwv(uj@yp+ z6_d!&5xhzhbHnkZWW7AqjwVH-=61SWtdbO;R)1EGUQTSZ`b)@LiqUE5oM~N^h0M?& z33^&CIWezxr;7bydh(Ch_yxW6wN7ch8IB_j8%oN!C;B<3v<;>1bIXE1g!pml=IY0U zqgk3)_ZTr=HnHoS{Jdu56l?!OZvC-WNIqcbUcctj9@g)yORRaOO|9teLXSFmCB;U^ zfJ~x?diM(ceEfu(q<5{WZ5}$)5M$xKCubyQ<=KHB+%_&O=T>HDK=Qpz236f^-TcSj z%o79N2?CpoZCjkdA#+Xko-KR2?4o3#3_)vv4Yc94e$@Y(RUW_dfx0ArOeawG`7-)O zvU?KQv$+?E%R@d{CVtg2j@@BJH{!D>!G-e9&7yW?5y*53SV4wDkCYjjIHHnFO_|v4d*3%UtaMrF`_MS(! z8e@3z{2(uM%Ptp`;*t?reh26HO9Z=@qse(;?_PYQqagQvmC&_A>!-!!o)HF@*f8q& zJYNH6qMa~Z5%dy$4rTb;E_o5?6SC@n2tX7d5D;__B*1aNWq=>x(!tvw5Oa`)0tkTc zgLCnK#sI=m$iKy+Xax9>OJJ~{99kEpr;FCrM`>g9&?qvv;dc`^^gbC}c7RGiK)}IO z@OK6Hzid48@$Evf@T$Poh}r^j)v8gy>J0k-v2ix0P%)=ymoljBJdIC9$X_Re<-A^G zackFeTW*ZBBlz`CE@mDKL4-fbDhlCnGfyKvbY_A!Xu%>TX#N3(;SaGrxf0evyndduY2y47N zV93<>mvRyJ5epN_9!;5Q#&_*~EPgELc=J9q^Kn)_6(6_=|vzyCXB+OT;`abWBr(s`F$q!Bay(Egk ztkitjp1B;hZXz)7o*?~GaeGYeI@}|Dz}Bh|Zr4DSa98SQnYkr*=0-9;3~v@8JBG7y zlm`Ur$z;(K@o^Ps4?O0!hPgB)Q%$XW^LfN$lEhs;hgC--%XtHqixCw{ zOY(!bq|LULTPbgL(YKMGYh8?<{mRrJ8KsWq>4dxdlOsE%YMFq-Ba44Ffc&iu z{^+{u7JK8~jFGK{2+c_42Ll%-0zcwcn6<2OpK}{!xDfUWBbhRAI#${5yWuSK^fv#B z#kp!@!y5Gfgbzmq9XF)ILO723+|d1cdBv^?Y1%)A)5BC0oRrGIt32BKPL(xDRgq8X zSkbXOduFPvTufDOUmez7^zNzEeXsVzFL)YmP7E&5wtr%&q&L)m3_4gezh{_6B{$me zaZrgQJ*`uP8yB0|dh~C^Bix&qqnGyBzr0}+80CWJ7i$EPf-HNsR5?SbZ)j_@h#$?T)jOtf$)ctGT1?lkb5F=jp hj6 { + return mapOf( + "signing.keyId" to getPropertyValue("SIGNING_KEY_ID"), + "signing.password" to getPropertyValue("SIGNING_PASSWORD"), + "signing.secretKeyRingFile" to getPropertyValue("SIGNING_SECRET_KEY_RING_FILE"), + "ossrhUsername" to getPropertyValue("OSSRH_USERNAME"), + "ossrhPassword" to getPropertyValue("OSSRH_PASSWORD"), + "sonatypeStagingProfileId" to getPropertyValue("SONATYPE_STAGING_PROFILE_ID") + ) +} + +fun getPropertyValue(key: String): String { + val property = if (project.hasProperty(key)) { + project.property(key) as String + } else { + System.getenv(key) + } + return property +} diff --git a/gradle.properties b/gradle.properties index 744ae81a..64e62dd9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,3 +10,6 @@ android.nonTransitiveRClass=true #MPP kotlin.mpp.enableCInteropCommonization=true + +#SDK version +versionCode = 0.0.1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 035e4f39..c9c59c6e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,6 +26,8 @@ truth = "1.1.5" kover = "0.7.5" ktlint = "12.0.3" detekt = "1.23.4" +dokka = "1.9.10" +nexus = "1.3.0" [libraries] androidx-credentials = { module = "androidx.credentials:credentials", version.ref = "credentials" } @@ -71,3 +73,5 @@ jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } +dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } +nexus = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 34d68d3b..7beb0044 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,20 +1,19 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { - repositories { - google() - gradlePluginPortal() - mavenCentral() - } + repositories { + google() + gradlePluginPortal() + mavenCentral() + } } dependencyResolutionManagement { - repositories { - google() - mavenCentral() - } + repositories { + google() + mavenCentral() + } } - rootProject.name = "Passkeys" include(":androidApp") -include(":shared") \ No newline at end of file +include(":shared") diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 235711c8..76fb27b4 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -1,17 +1,96 @@ plugins { - alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.androidLibrary) + alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.kotlinSerialization) alias(libs.plugins.kover) + alias(libs.plugins.dokka) + signing + `maven-publish` id("com.twilio.apkscale") id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3" id("co.touchlab.skie") version "0.6.1" } +val dokkaOutputDir = "$buildDir/dokka" + +tasks.dokkaHtml { + outputDirectory.set(file(dokkaOutputDir)) +} + +val deleteDokkaOutputDir by tasks.register("deleteDokkaOutputDirectory") { + delete(dokkaOutputDir) +} +val javadocJar = tasks.register("javadocJar") { + dependsOn(deleteDokkaOutputDir, tasks.dokkaHtml) + archiveClassifier.set("javaDoc") + from(dokkaOutputDir) +} + +val versionCode: String by extra +version = versionCode +val libId = "twilio-verify-passkeys" + +afterEvaluate { + publishing { + publications { + withType { + when (name) { + "kotlinMultiplatform" -> { + this.artifactId = "$libId-common" + } + else -> { + this.artifactId = "$libId-${name.lowercase()}" + } + } + groupId = "com.twilio" + artifact(javadocJar) + + pom { + name.set("Twilio Verify Passkeys Android") + description.set("Twilio Passkeys SDK enables developers to easily add Passkeys into their existing authentication flows within their own mobile applications. The Verify Passkeys SDK supports passkeys creation and authentication using the FIDO/WebAuthn industry standard.") + url.set("https://github.com/twilio/twilio-verify-passkeys") + licenses { + license { + name.set("Apache License, Version 2.0") + url.set("https://github.com/twilio/twilio-verify-passkeys/blob/main/LICENSE") + } + } + developers { + developer { + id.set("Twilio") + name.set("Twilio") + } + } + scm { + connection.set("scm:git:github.com/twilio/twilio-verify-passkeys.git") + developerConnection.set("scm:git:github.com/twilio/twilio-verify-passkeys.git") + url.set("https://github.com/twilio/twilio-verify-passkeys/tree/main") + } + } + } + } + } +} + + +// TODO: remove after https://youtrack.jetbrains.com/issue/KT-46466 is fixed +project.tasks.withType(AbstractPublishToMaven::class.java).configureEach { + dependsOn(project.tasks.withType(Sign::class.java)) +} + +signing { + sign(publishing.publications) +} + kotlin { applyDefaultHierarchyTemplate() androidTarget { + mavenPublication { + artifactId = "$libId-android" + } + publishLibraryVariants("release") + compilations.all { kotlinOptions { jvmTarget = "17" From 1307790c52eef0cdccc70109b7498091fdfdfce1 Mon Sep 17 00:00:00 2001 From: Sergio Fierro Perdomo Date: Wed, 28 Feb 2024 09:17:42 -0500 Subject: [PATCH 8/9] Add Apache-2.0 License (#6) --- LICENSE | 201 ++++++++++++++++ androidApp/build.gradle.kts | 16 ++ androidApp/detekt-baseline.xml | 16 ++ androidApp/src/main/AndroidManifest.xml | 16 ++ .../twilio/passkeys/android/LoginViewModel.kt | 217 ++++++++++-------- .../twilio/passkeys/android/MainActivity.kt | 16 ++ .../com/twilio/passkeys/android/PasskeyApp.kt | 16 ++ .../passkeys/android/api/AuthenticateApi.kt | 18 +- .../passkeys/android/api/RegistrationApi.kt | 20 +- .../android/di/TwilioPasskeyModule.kt | 16 ++ .../model/AuthenticateStartResponse.kt | 28 ++- .../model/AuthenticateVerificationResponse.kt | 16 ++ .../model/RegistrationStartResponse.kt | 32 ++- .../model/RegistrationVerificationResponse.kt | 16 ++ .../twilio/passkeys/android/pages/HomePage.kt | 16 ++ .../passkeys/android/pages/LoginPage.kt | 16 ++ .../repository/AuthenticateRepository.kt | 16 ++ .../android/repository/CreateRepository.kt | 16 ++ .../com/twilio/passkeys/android/ui/Color.kt | 16 ++ .../passkeys/android/ui/MyApplicationTheme.kt | 16 ++ androidApp/src/main/res/drawable/copy.xml | 16 ++ .../src/main/res/drawable/credit_card.xml | 16 ++ androidApp/src/main/res/drawable/dollar.xml | 16 ++ .../res/drawable/ic_launcher_background.xml | 16 ++ .../res/drawable/ic_launcher_foreground.xml | 16 ++ androidApp/src/main/res/drawable/menu.xml | 16 ++ androidApp/src/main/res/drawable/owl.xml | 16 ++ .../src/main/res/drawable/owl_inverted.xml | 16 ++ androidApp/src/main/res/drawable/twilio.xml | 16 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 18 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 18 +- .../res/values/ic_launcher_background.xml | 18 +- androidApp/src/main/res/values/strings.xml | 16 ++ androidApp/src/main/res/values/styles.xml | 18 +- build.gradle.kts | 49 ++-- gradle.properties | 16 ++ gradle/wrapper/gradle-wrapper.properties | 16 ++ gradlew | 4 +- .../Accounts.imageset/AdminAccounts.svg | 16 ++ .../Images/BillPay.imageset/Group 51477.svg | 16 ++ .../Images/Copy.imageset/CopySVG.svg | 18 +- .../CreditCard.imageset/CreditCardSVG.svg | 18 +- .../Images/Deposit.imageset/Group 51471.svg | 16 ++ .../Images/Loan.imageset/LoanSVG.svg | 18 +- .../Images/Menu.imageset/menu.svg | 16 ++ .../Images/More.imageset/Group.svg | 16 ++ .../Images/OwlBank.imageset/Group 51482.svg | 16 ++ .../Images/OwlCard.imageset/Rectangle 16.svg | 16 ++ .../Images/OwlWhite.imageset/Group 51439.svg | 16 ++ .../Images/PesosSign.imageset/Group 51478.svg | 16 ++ .../Search.imageset/icn_magnifying-glass.svg | 16 ++ .../icn_magnifying-glass (1).svg | 16 ++ .../Images/Transfer.imageset/Unsorted.svg | 16 ++ .../Images/Twilio.imageset/Vector.svg | 16 ++ settings.gradle.kts | 16 ++ shared/build.gradle.kts | 37 ++- shared/src/androidDebug/AndroidManifest.xml | 16 ++ .../com/twilio/passkeys/TestActivity.kt | 16 ++ ...catePasskeyMockingCredentialManagerTest.kt | 39 ++-- .../passkeys/AuthenticatePasskeyTest.kt | 24 +- ...eatePasskeyMockingCredentialManagerTest.kt | 37 +-- .../com/twilio/passkeys/CreatePasskeyTest.kt | 26 ++- .../passkeys/mocks/CredentialManagerMock.kt | 16 ++ .../com/twilio/passkeys/TwilioPasskey.kt | 20 +- .../passkeys/AndroidTwilioPasskeyTest.kt | 20 +- .../kotlin/com/twilio/passkeys/PasskeyData.kt | 16 ++ .../passkeys/AuthenticatePasskeyResult.kt | 16 ++ .../twilio/passkeys/CreatePasskeyResult.kt | 16 ++ .../twilio/passkeys/PasskeyPayloadMapper.kt | 16 ++ .../com/twilio/passkeys/TwilioPasskey.kt | 32 ++- .../passkeys/exception/TwilioException.kt | 16 ++ .../extensions/ByteArrayExtensions.kt | 16 ++ .../passkeys/extensions/StringExtensions.kt | 16 ++ .../models/AuthenticatePasskeyRequest.kt | 26 ++- .../models/AuthenticatePasskeyResponse.kt | 26 ++- .../passkeys/models/CreatePasskeyRequest.kt | 16 ++ .../passkeys/models/CreatePasskeyResponse.kt | 16 ++ .../twilio/passkeys/models/KeyCredential.kt | 16 ++ .../passkeys/PasskeyPayloadMapperTest.kt | 17 +- .../passkeys/exception/TwilioExceptionTest.kt | 18 +- .../extensions/ByteArrayExtensionsTest.kt | 17 +- .../extensions/StringExtensionsTest.kt | 17 +- .../com/twilio/passkeys/TwilioPasskey.kt | 20 +- .../com/twilio/passkeys/utils/DeviceUtils.kt | 16 ++ .../com/twilio/passkeys/TwilioPasskeyTest.kt | 16 ++ .../com/twilio/passkeys/mocks/UIDeviceMock.kt | 16 ++ .../twilio/passkeys/utils/DeviceUtilsTest.kt | 17 +- 87 files changed, 1761 insertions(+), 223 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a3527674 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2024 Twilio, inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + 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 + limitations under the License. diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index cf92b5f2..878dd5e6 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.kotlinAndroid) diff --git a/androidApp/detekt-baseline.xml b/androidApp/detekt-baseline.xml index 0d75593a..14f73d86 100644 --- a/androidApp/detekt-baseline.xml +++ b/androidApp/detekt-baseline.xml @@ -1,4 +1,20 @@ + + diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index f16ef8a8..46117fee 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -1,4 +1,20 @@ + + diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt b/androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt index 95f5331e..7068ccdd 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/LoginViewModel.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android import android.app.Activity @@ -21,127 +37,126 @@ import javax.inject.Inject @HiltViewModel class LoginViewModel -@Inject -constructor( - private val twilioPasskey: TwilioPasskey, - private val authenticateRepository: AuthenticateRepository, - private val createRepository: CreateRepository, -) : ViewModel() { - private val _state: MutableSharedFlow = - MutableSharedFlow( - replay = 1, - onBufferOverflow = BufferOverflow.DROP_OLDEST, - ) - val state = _state.asSharedFlow() + @Inject + constructor( + private val twilioPasskey: TwilioPasskey, + private val authenticateRepository: AuthenticateRepository, + private val createRepository: CreateRepository, + ) : ViewModel() { + private val _state: MutableSharedFlow = + MutableSharedFlow( + replay = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) + val state = _state.asSharedFlow() - fun create( - username: String, - activity: Activity, - ) { - viewModelScope.launch { - try { - val registrationStartResponse: RegistrationStartResponse = - createRepository.start( - username, - ) - val json = - Json { - encodeDefaults = true - ignoreUnknownKeys = true - explicitNulls = false - } - val challengePayload = json.encodeToString(registrationStartResponse) - when (val createPasskeyResult = twilioPasskey.create(challengePayload, AppContext(activity))) { - is CreatePasskeyResult.Error -> { - setErrorState(createPasskeyResult.error.message.toString()) - } + fun create( + username: String, + activity: Activity, + ) { + viewModelScope.launch { + try { + val registrationStartResponse: RegistrationStartResponse = + createRepository.start( + username, + ) + val json = + Json { + encodeDefaults = true + ignoreUnknownKeys = true + explicitNulls = false + } + val challengePayload = json.encodeToString(registrationStartResponse) + when (val createPasskeyResult = twilioPasskey.create(challengePayload, AppContext(activity))) { + is CreatePasskeyResult.Error -> { + setErrorState(createPasskeyResult.error.message.toString()) + } - is CreatePasskeyResult.Success -> { - try { - createRepository.verification( - rawId = createPasskeyResult.createPasskeyResponse.rawId, - id = createPasskeyResult.createPasskeyResponse.id, - clientDataJson = createPasskeyResult.createPasskeyResponse.clientDataJSON, - attestationObject = createPasskeyResult.createPasskeyResponse.attestationObject, - type = createPasskeyResult.createPasskeyResponse.type, - transports = createPasskeyResult.createPasskeyResponse.transports, - ) - _state.emit(LoginState.PasskeySuccess(username)) - } catch (e: Exception) { - setErrorState(e.message.toString()) + is CreatePasskeyResult.Success -> { + try { + createRepository.verification( + rawId = createPasskeyResult.createPasskeyResponse.rawId, + id = createPasskeyResult.createPasskeyResponse.id, + clientDataJson = createPasskeyResult.createPasskeyResponse.clientDataJSON, + attestationObject = createPasskeyResult.createPasskeyResponse.attestationObject, + type = createPasskeyResult.createPasskeyResponse.type, + transports = createPasskeyResult.createPasskeyResponse.transports, + ) + _state.emit(LoginState.PasskeySuccess(username)) + } catch (e: Exception) { + setErrorState(e.message.toString()) + } } } + } catch (e: Exception) { + setErrorState(e.message.toString()) } - } catch (e: Exception) { - setErrorState(e.message.toString()) } } - } - - fun authenticate(activity: Activity) { - viewModelScope.launch { - try { - val authenticationStartResponse = authenticateRepository.start() - val json = Json { encodeDefaults = true } - val challengePayload = json.encodeToString(authenticationStartResponse) - when (val authenticatePasskeyResult = twilioPasskey.authenticate(challengePayload, AppContext(activity))) { - is AuthenticatePasskeyResult.Error -> { - - setErrorState( - authenticatePasskeyResult.error.message, - ) - } - is AuthenticatePasskeyResult.Success -> { - try { - val response = - authenticatePasskeyResult.authenticatePasskeyResponse - authenticateRepository.verification( - rawId = response.rawId, - id = response.id, - clientDataJson = response.clientDataJSON, - userHandle = response.userHandle, - signature = response.signature, - authenticatorData = response.authenticatorData, - ) - _state.emit( - LoginState.PasskeySuccess( - "test", - ), + fun authenticate(activity: Activity) { + viewModelScope.launch { + try { + val authenticationStartResponse = authenticateRepository.start() + val json = Json { encodeDefaults = true } + val challengePayload = json.encodeToString(authenticationStartResponse) + when (val authenticatePasskeyResult = twilioPasskey.authenticate(challengePayload, AppContext(activity))) { + is AuthenticatePasskeyResult.Error -> { + setErrorState( + authenticatePasskeyResult.error.message, ) - } catch (e: Exception) { - setErrorState(e.message.toString()) + } + + is AuthenticatePasskeyResult.Success -> { + try { + val response = + authenticatePasskeyResult.authenticatePasskeyResponse + authenticateRepository.verification( + rawId = response.rawId, + id = response.id, + clientDataJson = response.clientDataJSON, + userHandle = response.userHandle, + signature = response.signature, + authenticatorData = response.authenticatorData, + ) + _state.emit( + LoginState.PasskeySuccess( + "test", + ), + ) + } catch (e: Exception) { + setErrorState(e.message.toString()) + } } } + } catch (e: Exception) { + setErrorState(e.message.toString()) } - } catch (e: Exception) { - setErrorState(e.message.toString()) } } - } - fun logout() { - viewModelScope.launch { - _state.emit(LoginState.Logout) + fun logout() { + viewModelScope.launch { + _state.emit(LoginState.Logout) + } } - } - fun areFieldsValid(phoneNumber: String): Boolean { - if (!android.util.Patterns.PHONE.matcher(phoneNumber).matches()) { - _state.tryEmit(LoginState.NumberError) - return false + fun areFieldsValid(phoneNumber: String): Boolean { + if (!android.util.Patterns.PHONE.matcher(phoneNumber).matches()) { + _state.tryEmit(LoginState.NumberError) + return false + } + return true } - return true - } - private fun setErrorState(message: String) { - _state.tryEmit( - LoginState.PasskeyError( - message, - ), - ) + private fun setErrorState(message: String) { + _state.tryEmit( + LoginState.PasskeyError( + message, + ), + ) + } } -} sealed interface LoginState { data object Initial : LoginState diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt b/androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt index f8ab4c00..f7f8e406 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/MainActivity.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android import android.os.Bundle diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt b/androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt index c1885ce3..b882fa00 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/PasskeyApp.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android import android.app.Application diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt b/androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt index d2c96f79..edf8d069 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/api/AuthenticateApi.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.api import com.twilio.passkeys.android.model.AuthenticateStartResponse @@ -12,7 +28,7 @@ interface AuthenticateApi { @POST("/authentication/verification") suspend fun authenticateVerification( - @Body authenticateVerificationRequest: AuthenticateVerificationRequest, + @Body authenticateVerificationRequest: AuthenticateVerificationRequest, ): AuthenticateVerificationResponse } diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt b/androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt index f2e273ea..c3197c92 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/api/RegistrationApi.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.api import com.twilio.passkeys.android.model.RegistrationStartResponse @@ -9,12 +25,12 @@ import retrofit2.http.POST interface RegistrationApi { @POST("/registration/start") suspend fun registrationStart( - @Body registrationStartRequest: RegistrationStartRequest, + @Body registrationStartRequest: RegistrationStartRequest, ): RegistrationStartResponse @POST("/registration/verification") suspend fun registrationVerification( - @Body registrationVerificationRequest: RegistrationVerificationRequest, + @Body registrationVerificationRequest: RegistrationVerificationRequest, ): RegistrationVerificationResponse } diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt b/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt index a2860356..c4e7687b 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/di/TwilioPasskeyModule.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.di import android.content.Context diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt index d093cbe4..999bf78e 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateStartResponse.kt @@ -1,19 +1,35 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.model import kotlinx.serialization.Serializable @Serializable data class AuthenticateStartResponse( - val publicKey: PublicKeyCredential, + val publicKey: PublicKeyCredential, ) @Serializable data class PublicKeyCredential( - val challenge: String, - val timeout: Int, - val rpId: String, - val allowCredentials: List, - val userVerification: String, + val challenge: String, + val timeout: Int, + val rpId: String, + val allowCredentials: List, + val userVerification: String, ) @Serializable diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt index e690b1aa..06760706 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/model/AuthenticateVerificationResponse.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.model import kotlinx.serialization.Serializable diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt index 7c4acd46..9418b503 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationStartResponse.kt @@ -1,17 +1,33 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.model import kotlinx.serialization.Serializable @Serializable data class RegistrationStartResponse( - val rp: RP, - val user: User, - val challenge: String, - val pubKeyCredParams: List, - val timeout: Int, - val excludeCredentials: List, - val authenticatorSelection: AuthenticatorSelection, - val attestation: String, + val rp: RP, + val user: User, + val challenge: String, + val pubKeyCredParams: List, + val timeout: Int, + val excludeCredentials: List, + val authenticatorSelection: AuthenticatorSelection, + val attestation: String, ) @Serializable diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt index 8dde93e7..3159990f 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/model/RegistrationVerificationResponse.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.model import kotlinx.serialization.Serializable diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt b/androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt index 7cbcfba2..7ee10a81 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/pages/HomePage.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.pages import androidx.compose.foundation.background diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt b/androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt index 46037cb1..8bb410da 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/pages/LoginPage.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.pages import androidx.compose.foundation.Image diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt b/androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt index 957c76cb..f0eccb48 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/repository/AuthenticateRepository.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.repository import com.twilio.passkeys.android.api.AuthenticateApi diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt b/androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt index 652c80f9..f0eb1785 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/repository/CreateRepository.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.repository import com.twilio.passkeys.android.api.RegistrationApi diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt b/androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt index 48babff5..318dedeb 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/ui/Color.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.ui import androidx.compose.ui.graphics.Color diff --git a/androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt b/androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt index 1361a6a7..dd7557c2 100644 --- a/androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt +++ b/androidApp/src/main/java/com/twilio/passkeys/android/ui/MyApplicationTheme.kt @@ -1,3 +1,19 @@ +/* + * Copyright © 2024 Twilio. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * 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 + * limitations under the License. + */ + package com.twilio.passkeys.android.ui import androidx.compose.foundation.isSystemInDarkTheme diff --git a/androidApp/src/main/res/drawable/copy.xml b/androidApp/src/main/res/drawable/copy.xml index df66e051..7e94ba2b 100644 --- a/androidApp/src/main/res/drawable/copy.xml +++ b/androidApp/src/main/res/drawable/copy.xml @@ -1,3 +1,19 @@ + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 7353dbd1..37f73365 100644 --- a/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,21 @@ + + - \ No newline at end of file + diff --git a/androidApp/src/main/res/values/ic_launcher_background.xml b/androidApp/src/main/res/values/ic_launcher_background.xml index 0f55997d..abc06dab 100644 --- a/androidApp/src/main/res/values/ic_launcher_background.xml +++ b/androidApp/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,20 @@ + + #0878FF - \ No newline at end of file + diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index d67614ee..08ce5ee2 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -1,4 +1,20 @@ + + PasskeysDemo diff --git a/androidApp/src/main/res/values/styles.xml b/androidApp/src/main/res/values/styles.xml index 6b4fa3d0..d6671da6 100644 --- a/androidApp/src/main/res/values/styles.xml +++ b/androidApp/src/main/res/values/styles.xml @@ -1,3 +1,19 @@ + +