Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .fvmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"flutter": "3.19.0"
"flutter": "3.35.7"
}
2 changes: 1 addition & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include: package:surf_lint_rules/analysis_options.yaml
include: package:flutter_lints/flutter.yaml
20 changes: 10 additions & 10 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ group 'ru.surfstudio.otp_autofill'
version '1.0-SNAPSHOT'

buildscript {
ext.kotlin_version = '1.9.23'
ext.kotlin_version = '2.0.21'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:8.5.1'
classpath 'com.android.tools.build:gradle:8.7.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand All @@ -29,15 +29,15 @@ android {
namespace 'ru.surfstudio.otp_autofill'
}

compileSdkVersion 33
compileSdkVersion 36

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}

sourceSets {
Expand All @@ -50,9 +50,9 @@ android {
}

dependencies {
implementation 'com.google.android.gms:play-services-auth:20.3.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'
implementation "androidx.activity:activity:1.5.1"
implementation "androidx.fragment:fragment:1.5.4"
implementation 'com.google.android.gms:play-services-auth:21.2.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.1.0'
implementation "androidx.activity:activity:1.9.3"
implementation "androidx.fragment:fragment:1.8.5"
}
}
4 changes: 3 additions & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ru.surfstudio.otp_autofill
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.os.Build
import android.util.Base64
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
Expand All @@ -20,9 +21,24 @@ class AppSignatureHelper(context: Context) : ContextWrapper(context) {
return try {
val packageName = packageName
val packageManager = packageManager
val signatures = packageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES).signatures
signatures.mapNotNull { hash(packageName, it.toCharsString()) }
val signatures = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val signingInfo = packageManager.getPackageInfo(
packageName,
PackageManager.GET_SIGNING_CERTIFICATES
).signingInfo
if (signingInfo?.hasMultipleSigners() == true) {
signingInfo.apkContentsSigners
} else {
signingInfo?.signingCertificateHistory
}
} else {
@Suppress("DEPRECATION")
packageManager.getPackageInfo(
packageName,
PackageManager.GET_SIGNATURES
).signatures
}
signatures?.mapNotNull { hash(packageName, it.toCharsString()) } ?: emptyList()
} catch (e: PackageManager.NameNotFoundException) {
emptyList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class OTPPlugin : FlutterPlugin, MethodCallHandler, PluginRegistry.ActivityResul
lastResult = null
} else {
// Consent denied. User can type OTC manually.
lastResult?.error("USER_DENIED", "User denied SMS consent", null)
lastResult = null
}

credentialPickerRequest -> if (resultCode == Activity.RESULT_OK && data != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ class SmsRetrieverReceiver : BroadcastReceiver() {
if (intent?.action == SmsRetriever.SMS_RETRIEVED_ACTION) {

val extras = intent.extras
val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status
val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as? Status ?: return

when (smsRetrieverStatus.statusCode) {
CommonStatusCodes.SUCCESS -> {
extras.get(SmsRetriever.EXTRA_SMS_MESSAGE)?.also {
extras?.get(SmsRetriever.EXTRA_SMS_MESSAGE)?.also {
smsBroadcastReceiverListener.onSuccess(it as String)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ru.surfstudio.otp_autofill
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Status
Expand All @@ -16,11 +17,17 @@ class SmsUserConsentReceiver : BroadcastReceiver() {
if (intent?.action == SmsRetriever.SMS_RETRIEVED_ACTION) {

val extras = intent.extras
val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as Status
val smsRetrieverStatus = extras?.get(SmsRetriever.EXTRA_STATUS) as? Status ?: return

when (smsRetrieverStatus.statusCode) {
CommonStatusCodes.SUCCESS -> {
extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)?.also {
val consentIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
extras?.getParcelable(SmsRetriever.EXTRA_CONSENT_INTENT, Intent::class.java)
} else {
@Suppress("DEPRECATION")
extras?.getParcelable(SmsRetriever.EXTRA_CONSENT_INTENT)
}
consentIntent?.also {
smsBroadcastReceiverListener.onSuccess(it)
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include: package:surf_lint_rules/analysis_options.yaml
include: package:flutter_lints/flutter.yaml
6 changes: 3 additions & 3 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ android {
ndkVersion flutter.ndkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = '1.8'
jvmTarget = '17'
}

sourceSets {
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.8.22'
ext.kotlin_version = '2.0.21'
repositories {
google()
mavenCentral()
Expand Down
3 changes: 2 additions & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Tue Nov 25 14:25:48 CET 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void main() {
}

class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
const MyApp({super.key});

@override
_MyAppState createState() => _MyAppState();
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:


dev_dependencies:
surf_lint_rules: ^2.0.0
flutter_lints: ^5.0.0

flutter:
uses-material-design: true
9 changes: 9 additions & 0 deletions lib/src/otp_text_edit_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,13 @@ class OTPTextEditController extends TextEditingController {
void checkForComplete() {
if (text.length == codeLength) onCodeReceive?.call(text);
}

@override
void dispose() {
// Remove the listener added in constructor
removeListener(checkForComplete);
// Stop listening for OTP codes and unregister broadcast receivers
stopListen();
super.dispose();
}
}
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ dependencies:
sdk: flutter

dev_dependencies:
melos: 6.3.1
dependency_validator: ^3.0.0
flutter_test:
sdk: flutter

mocktail: ^0.2.0
surf_lint_rules: ^2.0.0
flutter_lints: ^5.0.0

environment:
sdk: ">=2.18.0 <4.0.0"
Expand Down
7 changes: 4 additions & 3 deletions test/otp_text_edit_controller_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:async';

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:otp_autofill/otp_autofill.dart';
import 'package:otp_autofill/src/util/platform_wrapper.dart';
import 'package:surf_lint_rules/surf_lint_rules.dart';

const testCode = '54321';
const codeFromTestStrategyFirst = '23451';
Expand Down Expand Up @@ -64,8 +65,8 @@ void main() {
codeOnCodeReceive = code;
},
platform: platformWrapper,
onTimeOutException: onTimeOutException,
errorHandler: onException,
onTimeOutException: onTimeOutException.call,
errorHandler: onException.call,
);
});

Expand Down