Skip to content

Commit

Permalink
Merge pull request #1 from TandohAnthonyNwiAckah/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
TandohAnthonyNwiAckah authored Sep 20, 2024
2 parents 6669acc + 45deb0a commit cec50f5
Show file tree
Hide file tree
Showing 20 changed files with 425 additions and 143 deletions.
8 changes: 7 additions & 1 deletion .dart_tool/package_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
"packageUri": "lib/",
"languageVersion": "3.2"
},
{
"name": "lint",
"rootUri": "file:///Users/tanacom/.pub-cache/hosted/pub.dev/lint-2.3.0",
"packageUri": "lib/",
"languageVersion": "3.2"
},
{
"name": "lints",
"rootUri": "file:///Users/tanacom/.pub-cache/hosted/pub.dev/lints-4.0.0",
Expand Down Expand Up @@ -170,7 +176,7 @@
"languageVersion": "3.5"
}
],
"generated": "2024-09-14T22:18:04.838538Z",
"generated": "2024-09-19T14:51:32.149982Z",
"generator": "pub",
"generatorVersion": "3.5.2",
"flutterRoot": "file:///Users/tanacom/flutter",
Expand Down
4 changes: 4 additions & 0 deletions .dart_tool/package_config_subset
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ leak_tracker_testing
3.2
file:///Users/tanacom/.pub-cache/hosted/pub.dev/leak_tracker_testing-3.0.1/
file:///Users/tanacom/.pub-cache/hosted/pub.dev/leak_tracker_testing-3.0.1/lib/
lint
3.2
file:///Users/tanacom/.pub-cache/hosted/pub.dev/lint-2.3.0/
file:///Users/tanacom/.pub-cache/hosted/pub.dev/lint-2.3.0/lib/
lints
3.1
file:///Users/tanacom/.pub-cache/hosted/pub.dev/lints-4.0.0/
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Flutter Lint

on:
pull_request:
branches: [ "master", "development"]

jobs:
analyze:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
flutter-version: 3.24.2
- run: flutter --version

- name: Install dependencies
run: flutter pub get

- name: Run Dart analyzer
run: flutter analyze
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.2.2
## 1.0.0
- Upgrade dependencies.
- Code cleanup.

## 0.2.2
- initial release.
100 changes: 99 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,100 @@
# otp_autofill_sms
A versatile and efficient solution designed to enhance the user experience by automating the process of filling in OTPs sent via SMS.

`otp_autofill_sms` is a Flutter plugin designed to simplify OTP (One-Time Password) autofill for
Android applications.

This plugin is available only for Android, as iOS handles OTP autofill natively. While iOS users
benefit from built-in OTP autofill functionality, this plugin provides a seamless experience for
Android users by managing OTP autofill without requiring SMS read permissions, thus enhancing user
convenience.

## Features

- **Automatic OTP Detection**: Automatically captures and fills OTPs sent via SMS, enhancing user
convenience.

- **No SMS Permissions Required**: Utilizes
the [SMS User Consent API](https://developers.google.com/identity/sms-retriever/user-consent/overview)
to function without needing explicit SMS read permissions.
- **Easy Integration**: Simple setup and integration with your Flutter project.

## Screenshots

| Default Screen | OTP Autofill |
|-------------------------------------------|-------------------------------------------|
| ![Main Page](screenshots/screenshot1.png) | ![Main Page](screenshots/screenshot2.png) |

## How It Works

The plugin leverages Google's SMS Retriever API to detect OTPs automatically. To ensure proper
detection, the SMS message must adhere to specific formatting rules:

### SMS Formatting Guidelines

- **Length**: SMS should be no longer than 140 bytes.

- **Content**: The message must contain a one-time code for user verification.

- **End String**: The message should end with an 11-character hash string that identifies your app.

### Example SMS Format

> Your ExampleApp code is: 915456 FA+9qCVSz
**Make sure to generate the Signature Code for both the release and debug versions of your app and append it to your message.**


## Installation

To add `otp_autofill_sms` to your Flutter project, follow these steps:

1. **Add Dependency**: Include the plugin in your `pubspec.yaml` file:
```yaml
dependencies:
otp_autofill_sms: ^1.0.0
```
2. **Install Packages**: Run `flutter pub get` to fetch the package.

3. **Android Configuration**: Follow the setup instructions below to configure your Android project.

## Setup Instructions

1 **Flutter Integration**: Import and initialize the plugin in your Dart code:
```dart
import 'package:otp_autofill_sms/otp_autofill_sms.dart';
```

2 **Basic Usage**:
```dart
// Get the app signature code.
Future<void> _getSignatureCode() async {
String? signature = await OtpAutofillSms.getAppSignature();
print("Signature: $signature");
}
// Start listening for incoming SMS messages
void _startListeningSms() {
OtpAutofillSms.startListeningSms().then((message) {
setState(() {
print("Message: $message");
});
});
}
```


## Contributing

Contributions are welcome! If you find any bugs or have ideas for improvements, please submit a pull
request or open an issue on
the [otp_autofill_sms repository](https://github.com/TandohAnthonyNwiAckah/otp_autofill_sms)


10 changes: 5 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
}

dependencies {
classpath("com.android.tools.build:gradle:8.1.0")
classpath("com.android.tools.build:gradle:8.1.4")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
Expand Down Expand Up @@ -53,11 +53,11 @@ android {

dependencies {
// implementation files('src/main/libs/flutter.jar')
implementation 'com.google.android.gms:play-services-auth:20.7.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.2'
implementation "androidx.core:core-ktx:1.12.0"
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.core:core-ktx:1.13.1"
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
testImplementation("org.mockito:mockito-core:5.2.0")

}

Expand Down
22 changes: 20 additions & 2 deletions android/src/main/kotlin/com/tanacom/otp_autofill_sms/MyApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,26 @@ import java.security.NoSuchAlgorithmException
import java.util.Arrays


/** MyApp **/
/**
* MyApp
* A custom ContextWrapper to handle application-specific context operations.
*
* @param context The base context to wrap.
*/
class MyApp(context: Context) : ContextWrapper(context) {

companion object {
val TAG = MyApp::class.java.simpleName
val TAG: String = MyApp::class.java.simpleName
private const val HASH_TYPE = "SHA-256"
const val NUM_HASHED_BYTES = 9
const val NUM_BASE64_CHAR = 11
}

/**
* Retrieves the application signatures.
*
* @return A list of hashed signatures for the application.
*/
fun getAppSignatures(): ArrayList<String> {
val appCodes = ArrayList<String>()

Expand Down Expand Up @@ -68,6 +78,14 @@ class MyApp(context: Context) : ContextWrapper(context) {
}
}


/**
* Hashes the package name and signature.
*
* @param packageName The package name to hash.
* @param signature The signature to hash.
* @return A hashed package name and signature.
*/
@SuppressLint("NewApi")
private fun hash(packageName: String, signature: String): String? {
val appInfo = "$packageName $signature"
Expand Down
14 changes: 11 additions & 3 deletions android/src/main/kotlin/com/tanacom/otp_autofill_sms/MyListener.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.tanacom.otp_autofill_sms


/** MyListener **/
/**
* MyListener interface to handle OTP events.
*/
interface MyListener {
/**
* Called when an OTP is received.
* @param message The received OTP message.
*/
fun onOtpReceived(message: String?)
fun onOtpTimeout()

/**
* Called when OTP retrieval times out.
*/
fun onOtpTimeout()
}
Loading

0 comments on commit cec50f5

Please sign in to comment.