cordova-plugin-sms-retriever-manager 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "cordova-plugin-sms-retriever-manager",
3
+ "version": "1.0.3",
4
+ "description": "Cross-platform plugin for Cordova / PhoneGap to to easily retrive SMS using Google SMS retriver API. Available for Android.",
5
+ "cordova": {
6
+ "id": "cordova-plugin-sms-retriever-manager",
7
+ "platforms": [
8
+ "android"
9
+ ]
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/hanatharesh2712/ionic-native-sms-retriever-plugin-master.git"
14
+ },
15
+ "keywords": [
16
+ "cordova",
17
+ "phonegap",
18
+ "sms",
19
+ "ecosystem:cordova",
20
+ "cordova-android"
21
+ ],
22
+ "engines": [
23
+ {
24
+ "name": "cordova",
25
+ "version": ">=3.0.0"
26
+ }
27
+ ],
28
+ "author": "Haresh Hanat",
29
+ "license": "DEV",
30
+ "bugs": {
31
+ "url": "https://github.com/hanatharesh2712/ionic-native-sms-retriever-plugin-master/issues"
32
+ },
33
+ "homepage": "https://github.com/hanatharesh2712/ionic-native-sms-retriever-plugin-master"
34
+ }
package/plugin.xml ADDED
@@ -0,0 +1,27 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
3
+ id="cordova-plugin-sms-retriever-manager" version="1.0.3">
4
+ <name>Device</name>
5
+ <description>Cordova SMS Retriver Plugin</description>
6
+ <license>MIT</license>
7
+ <keywords>ionic, ionic3, cordova, cordova-plugin, phonegap-plugin, ionic-framework, ionic-cordova, sms, sms-verificationm automatic SMS receive</keywords>
8
+
9
+ <js-module name="AndroidSmsRetriever" src="www/smsRetriever.js">
10
+ <clobbers target="cordova.plugins.smsRetriever" />
11
+ </js-module>
12
+ <engines>
13
+ <engine name="cordova" version=">=3.6.0"></engine>
14
+ </engines>
15
+ <platform name="android">
16
+ <preference name="PLAY_SERVICES_VERSION" default="15.0.1"/>
17
+ <framework src="com.google.android.gms:play-services-auth-api-phone:$PLAY_SERVICES_VERSION"/>
18
+ <source-file src="src/android/com/codingsans/ionic/smsRetriever/AndroidSmsRetriever.java"
19
+ target-dir="src/com/codingsans/ionic/smsRetriever"></source-file>
20
+
21
+ <config-file target="res/xml/config.xml" parent="/*">
22
+ <feature name="AndroidSmsRetriever">
23
+ <param name="android-package" value="com.codingsans.ionic.smsRetriever.AndroidSmsRetriever" />
24
+ </feature>
25
+ </config-file>
26
+ </platform>
27
+ </plugin>
package/readme.md ADDED
@@ -0,0 +1,223 @@
1
+ # ionic-native-sms-retriever-plugin-master
2
+ # Cordova SMS retriver Plugin
3
+
4
+ Cross-platform plugin for Cordova / PhoneGap to to easily retrive SMS for your APP without need permission of SMS_READ. Available for **Android**.
5
+
6
+ ## Installing the plugin
7
+
8
+ Using the Cordova CLI run:
9
+
10
+ ```
11
+ ionic cordova plugin add cordova-plugin-sms-retriever-manager
12
+ npm install @ionic-native/sms-retriever
13
+ ```
14
+
15
+ It is also possible to install via repo url directly (unstable), run :
16
+
17
+ ```sh
18
+ ionic cordova plugin add https://github.com/hanatharesh2712/ionic-native-sms-retriever-plugin-master.git
19
+ ```
20
+ You can find working Demo for Cordova here: https://github.com/hanatharesh2712/automatic-sms-cordova/tree/main/hello
21
+ ## Using the plugin
22
+ HTML
23
+
24
+ ```html
25
+ <input type="button" class="hashCode" value="Get App Hash" />
26
+ <input type="button" class="startWatching" value="Start watching SMS" />
27
+ ```
28
+
29
+ Javascript
30
+
31
+ ```js
32
+
33
+ document.querySelector('.hashCode').addEventListener('click', this.getAppHash);
34
+ document.querySelector('.startWatching').addEventListener('click', this.retriveSMS);
35
+
36
+ var app = {
37
+ getAppHash: function() {
38
+ window['cordova']['plugins']['smsRetriever']['getAppHash'](
39
+ (result) => {
40
+ // Once you get this hash code of your app. Please remove this code.
41
+ alert(result);
42
+ console.log('Hash', result);
43
+ },
44
+ (err) => {
45
+ console.log(err);
46
+ });
47
+ },
48
+
49
+ retriveSMS: function() {
50
+ window['cordova']['plugins']['smsRetriever']['startWatching'](
51
+ // the first callback is the success callback. We got back the native code’s result here.
52
+ (result) => {
53
+ alert(result.Message);
54
+ console.log('Message', result);
55
+ },
56
+ // the second is the error callback where we get back the errors
57
+ (err) => {
58
+ console.log(err);
59
+ });
60
+ }
61
+ };
62
+ ```
63
+ You can find working Demo for Ionic 4 here: https://github.com/hanatharesh2712/sms-plugin-test
64
+
65
+ Typescript (Ionic 4)
66
+ ```typescript
67
+ import { SmsRetriever } from '@ionic-native/sms-retriever/ngx';
68
+
69
+
70
+ constructor(private smsRetriever: SmsRetriever) { }
71
+
72
+ ...
73
+
74
+ // This function is to get hash string of APP.
75
+ // * @return {Promise<string>} Returns a promise that resolves when successfully generate hash of APP.
76
+ this.smsRetriever.getAppHash()
77
+ .then((res: any) => console.log(res))
78
+ .catch((error: any) => console.error(error));
79
+
80
+
81
+ // * This function start wathching message arrive event and retrive message text.
82
+ // * @return {Promise<string>} Returns a promise that resolves when retrives SMS text or TIMEOUT after 5 min.
83
+ this.smsRetriever.startWatching()
84
+ .then((res: any) => console.log(res))
85
+ .catch((error: any) => console.error(error));
86
+
87
+ ```
88
+
89
+ You can find working Demo for Ionic 3 here: https://github.com/hanatharesh2712/sms-plugin-test-ionic-3
90
+
91
+ Typescript (Ionic 3)
92
+ ```typescript
93
+
94
+ import { SmsRetriever } from '@ionic-native/sms-retriever/ngx';
95
+ var smsRetriever = window['cordova']['plugins']['smsRetriever'];
96
+
97
+ public smsTextmessage: string = '';
98
+ public appHashString: string = '';
99
+ constructor(private smsRetriever: SmsRetriever) { }
100
+
101
+ ...
102
+
103
+ getHashCode() {
104
+ smsRetriever['getAppHash']((res) => {
105
+ this.appHashString = res;
106
+ console.log(res);
107
+ }, (err) => {
108
+ console.warn(err);
109
+ }
110
+ );
111
+ }
112
+
113
+ getSMS() {
114
+ smsRetriever['startWatching']((res) => {
115
+ this.smsTextmessage = res.Message;
116
+ console.log(res);
117
+ }, (err) => {
118
+ console.warn(err);
119
+ }
120
+ );
121
+ }
122
+ ```
123
+ Flow to test:
124
+ [![flow](https://raw.githubusercontent.com/hanatharesh2712/automatic-sms-cordova/main/hello/res/ref-images/sms%20plugin%20demo.png)](https://raw.githubusercontent.com/hanatharesh2712/automatic-sms-cordova/main/hello/res/ref-images/sms%20plugin%20demo.png)
125
+
126
+
127
+
128
+ You need to send your application hash in SMS when you are sending from your backend. to generate the hash of your application read this: https://developers.google.com/identity/sms-retriever/verify
129
+
130
+ To get your application hash code:
131
+
132
+ * Without the correct hash, your app won't recieve the message callback. This only needs to be
133
+ * generated once per app and stored. Then you can remove this function from your code.
134
+
135
+
136
+
137
+
138
+ BUILD FAILED
139
+
140
+ The problem is that you need to make sure that you set the target to android-19 or later in your ./platforms/android/project.properties file like this:
141
+
142
+ # Project target.
143
+ target=android-19
144
+
145
+
146
+ ## Donations
147
+
148
+ If your app is successful or if you are working for a company, please consider donating some beer money :beer::
149
+
150
+ [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YP2LMRCJMGTNJ&source=url)
151
+
152
+ Keep in mind that I am maintaining this repository on my free time so thank you for considering a donation. :+1:
153
+
154
+
155
+ ## Contributing
156
+
157
+ I believe that everything is working, feel free to put in an issue or to fork and make pull requests if you want to add a new feature.
158
+
159
+ Things you can fix:
160
+ * Allow for null number to be passed in
161
+ Right now, it breaks when a null value is passed in for a number, but it works if it's a blank string, and allows the user to pick the number
162
+ It should automatically convert a null value to an empty string
163
+
164
+ Thanks for considering contributing to this project.
165
+
166
+ ### Finding something to do
167
+
168
+ Ask, or pick an issue and comment on it announcing your desire to work on it. Ideally wait until we assign it to you to minimize work duplication.
169
+
170
+ ### Reporting an issue
171
+
172
+ - Search existing issues before raising a new one.
173
+
174
+ - Include as much detail as possible.
175
+
176
+ ### Pull requests
177
+
178
+ - Make it clear in the issue tracker what you are working on, so that someone else doesn't duplicate the work.
179
+
180
+ - Use a feature branch, not master.
181
+
182
+ - Rebase your feature branch onto origin/master before raising the PR.
183
+
184
+ - Keep up to date with changes in master so your PR is easy to merge.
185
+
186
+ - Be descriptive in your PR message: what is it for, why is it needed, etc.
187
+
188
+ - Make sure the tests pass
189
+
190
+ - Squash related commits as much as possible.
191
+
192
+ ### Coding style
193
+
194
+ - Try to match the existing indent style.
195
+
196
+ - Don't mix platform-specific stuff into the main code.
197
+
198
+
199
+
200
+
201
+ ## History
202
+
203
+
204
+ ## License
205
+
206
+ The MIT License
207
+
208
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
209
+ this software and associated documentation files (the "Software"), to deal in
210
+ the Software without restriction, including without limitation the rights to
211
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
212
+ the Software, and to permit persons to whom the Software is furnished to do so,
213
+ subject to the following conditions:
214
+
215
+ The above copyright notice and this permission notice shall be included in all
216
+ copies or substantial portions of the Software.
217
+
218
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
219
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
220
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
221
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
222
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
223
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,234 @@
1
+ package com.codingsans.ionic.smsRetriever;
2
+
3
+ import org.apache.cordova.CallbackContext;
4
+ import org.apache.cordova.CordovaInterface;
5
+ import org.apache.cordova.CordovaWebView;
6
+ import org.apache.cordova.CordovaPlugin;
7
+ import org.apache.cordova.PluginResult;
8
+ import org.apache.cordova.LOG;
9
+
10
+ import android.content.BroadcastReceiver;
11
+ import android.content.Intent;
12
+ import android.content.IntentFilter;
13
+ import android.os.Bundle;
14
+ import android.util.Log;
15
+ import android.widget.Toast;
16
+
17
+ import org.json.JSONArray;
18
+ import org.json.JSONObject;
19
+ import org.json.JSONException;
20
+
21
+ import android.content.Context;
22
+ import com.google.android.gms.auth.api.phone.SmsRetriever;
23
+ import com.google.android.gms.auth.api.phone.SmsRetrieverClient;
24
+ import com.google.android.gms.common.api.Status;
25
+ import com.google.android.gms.tasks.OnFailureListener;
26
+ import com.google.android.gms.tasks.OnSuccessListener;
27
+ import com.google.android.gms.common.api.CommonStatusCodes;
28
+ import com.google.android.gms.tasks.Task;
29
+
30
+ import java.util.ArrayList;
31
+
32
+ import static com.google.android.gms.common.api.CommonStatusCodes.*;
33
+
34
+ import android.content.ContextWrapper;
35
+ import android.content.pm.PackageManager;
36
+ import android.content.pm.Signature;
37
+ import android.util.Base64;
38
+
39
+ import java.nio.charset.StandardCharsets;
40
+ import java.security.MessageDigest;
41
+ import java.security.NoSuchAlgorithmException;
42
+ import java.util.Arrays;
43
+
44
+ public class AndroidSmsRetriever extends CordovaPlugin {
45
+
46
+ private SmsRetrieverClient smsRetrieverClient;
47
+ //public static final int MAX_TIMEOUT = 300000; // 5 mins in millis
48
+ private static final String TAG = AndroidSmsRetriever.class.getSimpleName();
49
+
50
+ private static final String HASH_TYPE = "SHA-256";
51
+ public static final int NUM_HASHED_BYTES = 9;
52
+ public static final int NUM_BASE64_CHAR = 11;
53
+
54
+ private CallbackContext callbackContext;
55
+ private JSONObject data = new JSONObject();
56
+
57
+ @Override
58
+ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
59
+ LOG.v(TAG, "SmsRetriever: initialization");
60
+ //Toast.makeText(this.cordova.getActivity().getApplicationContext(),"SmsRetriever: initialization", Toast.LENGTH_SHORT).show();
61
+
62
+ super.initialize(cordova, webView);
63
+
64
+ // Get an instance of SmsRetrieverClient, used to start listening for a matching
65
+ // SMS message.
66
+ smsRetrieverClient = SmsRetriever.getClient(this.cordova.getActivity().getApplicationContext());
67
+ }
68
+
69
+ /**
70
+ * Get all the app signatures for the current package
71
+ * @return
72
+ */
73
+ public ArrayList<String> getAppSignatures() {
74
+ ArrayList<String> appCodes = new ArrayList<>();
75
+
76
+ try {
77
+ // Get all package signatures for the current package
78
+ String packageName = cordova.getActivity().getApplicationContext().getPackageName();
79
+ PackageManager packageManager = cordova.getActivity().getApplicationContext().getPackageManager();
80
+ Signature[] signatures = packageManager.getPackageInfo(packageName,
81
+ PackageManager.GET_SIGNATURES).signatures;
82
+
83
+ // For each signature create a compatible hash
84
+ for (Signature signature : signatures) {
85
+ String hash = hash(packageName, signature.toCharsString());
86
+ if (hash != null) {
87
+ appCodes.add(String.format("%s", hash));
88
+ }
89
+ }
90
+ } catch (PackageManager.NameNotFoundException e) {
91
+ Log.e(TAG, "Unable to find package to obtain hash.", e);
92
+ }
93
+ return appCodes;
94
+ }
95
+
96
+ private static String hash(String packageName, String signature) {
97
+ String appInfo = packageName + " " + signature;
98
+ try {
99
+ MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
100
+ messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
101
+ byte[] hashSignature = messageDigest.digest();
102
+
103
+ // truncated into NUM_HASHED_BYTES
104
+ hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
105
+ // encode into Base64
106
+ String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
107
+ base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);
108
+
109
+ Log.d(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
110
+
111
+ return base64Hash;
112
+ } catch (NoSuchAlgorithmException e) {
113
+ Log.e(TAG, "hash:NoSuchAlgorithm", e);
114
+ }
115
+ return null;
116
+ }
117
+
118
+ @Override
119
+ public void onDestroy() {
120
+ try {
121
+ if (mMessageReceiver != null) {
122
+ this.cordova.getActivity().getApplicationContext().unregisterReceiver(mMessageReceiver);
123
+ mMessageReceiver = null;
124
+ }
125
+ } catch(IllegalArgumentException e) {
126
+ e.printStackTrace();
127
+ }
128
+ }
129
+
130
+ @Override
131
+ public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
132
+ this.callbackContext = callbackContext;
133
+
134
+ LOG.v(TAG, "Executing action: " + action);
135
+ //Toast.makeText(this.cordova.getActivity().getApplicationContext(),"Executing action: " + action, Toast.LENGTH_SHORT).show();
136
+
137
+ if ("start".equals(action)) {
138
+ // Starts SmsRetriever, which waits for ONE matching SMS message until timeout
139
+ // (5 minutes). The matching SMS message will be sent via a Broadcast Intent with
140
+ // action SmsRetriever#SMS_RETRIEVED_ACTION.
141
+ Task<Void> task = smsRetrieverClient.startSmsRetriever();
142
+
143
+ // Listen for success/failure of the start Task. If in a background thread, this
144
+ // can be made blocking using Tasks.await(task, [timeout]);
145
+ task.addOnSuccessListener(new OnSuccessListener<Void>() {
146
+ @Override
147
+ public void onSuccess(Void aVoid) {
148
+ // Successfully started retriever, expect broadcast intent
149
+ LOG.v(TAG, "Executing action: addOnSuccessListener");
150
+ //Toast.makeText(cordova.getActivity().getApplicationContext(),"Executing action: addOnSuccessListener", Toast.LENGTH_SHORT).show();
151
+
152
+ IntentFilter intentFilter = new IntentFilter();
153
+ intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);
154
+ cordova.getActivity().getApplicationContext().registerReceiver(mMessageReceiver, intentFilter);
155
+ }
156
+ });
157
+
158
+ task.addOnFailureListener(new OnFailureListener() {
159
+ @Override
160
+ public void onFailure(Exception e) {
161
+ // Failed to start retriever, inspect Exception for more details
162
+ LOG.v(TAG, "Executing action: addOnFailureListener");
163
+ //Toast.makeText(cordova.getActivity().getApplicationContext(),"Executing action: addOnFailureListener", Toast.LENGTH_SHORT).show();
164
+ }
165
+ });
166
+
167
+ PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
168
+ r.setKeepCallback(true);
169
+ callbackContext.sendPluginResult(r);
170
+
171
+ return true;
172
+
173
+ }
174
+ else if ("hash".equals(action)) {
175
+
176
+ ArrayList<String> strHashCodes = getAppSignatures();
177
+
178
+ if(strHashCodes.size() == 0 || strHashCodes.get(0) == null){
179
+
180
+ String err = "Unable to find package to obtain hash code of application";
181
+ PluginResult result = new PluginResult(PluginResult.Status.ERROR, err);
182
+ callbackContext.sendPluginResult(result);
183
+
184
+ } else {
185
+
186
+ String strApplicationHash = strHashCodes.get(0);
187
+ PluginResult result = new PluginResult(PluginResult.Status.OK, strApplicationHash);
188
+ callbackContext.sendPluginResult(result);
189
+
190
+ }
191
+ }
192
+
193
+ // Returning false results in a "MethodNotFound" error.
194
+ return false;
195
+ }
196
+
197
+ // Our handler for received Intents. This will be called whenever an Intent
198
+ // with an action named "custom-event-name" is broadcasted.
199
+ private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
200
+ @Override
201
+ public void onReceive(Context context, Intent intent) {
202
+
203
+ if (intent.getAction().equals(SmsRetriever.SMS_RETRIEVED_ACTION)) {
204
+ final Bundle extra = intent.getExtras();
205
+ if (extra != null && extra.containsKey(SmsRetriever.EXTRA_STATUS)) {
206
+ Status status = (Status) extra.get(SmsRetriever.EXTRA_STATUS);
207
+ switch (status.getStatusCode()) {
208
+ case CommonStatusCodes.SUCCESS:
209
+ final String message = extra.getString(SmsRetriever.EXTRA_SMS_MESSAGE);
210
+ //if (!StringUtils.hasContent(message)) return;
211
+
212
+ Log.d(TAG, message);
213
+
214
+ data = new JSONObject();
215
+ try {
216
+ data.put("Message",message);
217
+ } catch(JSONException e) {}
218
+
219
+ //Toast.makeText(cordova.getActivity().getApplicationContext(),"Message: "+ message, Toast.LENGTH_LONG).show();
220
+ PluginResult result = new PluginResult(PluginResult.Status.OK, data);
221
+ callbackContext.sendPluginResult(result);
222
+
223
+ break;
224
+ case CommonStatusCodes.TIMEOUT:
225
+
226
+ PluginResult resultTimeout = new PluginResult(PluginResult.Status.ERROR, "TIMEOUT");
227
+ callbackContext.sendPluginResult(resultTimeout);
228
+ break;
229
+ }
230
+ }
231
+ }
232
+ };
233
+ };
234
+ }
@@ -0,0 +1,19 @@
1
+ var SmsRetrieverLoader = function(require, exports, module) {
2
+ var exec = require('cordova/exec');
3
+
4
+ function SmsRetriever() {}
5
+
6
+ SmsRetriever.prototype.startWatching = function(success, failure) {
7
+ exec(success, failure, 'AndroidSmsRetriever', 'start', []);
8
+ };
9
+
10
+ SmsRetriever.prototype.getAppHash = function (success, failure) {
11
+ exec(success, failure, 'AndroidSmsRetriever', 'hash', []);
12
+ };
13
+ var smsRetriever = new SmsRetriever();
14
+ module.exports = smsRetriever;
15
+ };
16
+
17
+ SmsRetrieverLoader(require, exports, module);
18
+
19
+ cordova.define("cordova/plugin/SmsRetriever", SmsRetrieverLoader);