webviewsinjector

Android WebViews autologin system and dynamic javascript injector

License

License

Categories

Categories

Net
GroupId

GroupId

net.neferett
ArtifactId

ArtifactId

webviewsinjector
Last Version

Last Version

2.1.6
Release Date

Release Date

Type

Type

aar
Description

Description

webviewsinjector
Android WebViews autologin system and dynamic javascript injector
Project URL

Project URL

https://github.com/jordanbonaldi/WebViewsInjector
Source Code Management

Source Code Management

https://github.com/jordanbonaldi/WebViewsInjector/tree/master

Download webviewsinjector

How to add to project

<!-- https://jarcasting.com/artifacts/net.neferett/webviewsinjector/ -->
<dependency>
    <groupId>net.neferett</groupId>
    <artifactId>webviewsinjector</artifactId>
    <version>2.1.6</version>
    <type>aar</type>
</dependency>
// https://jarcasting.com/artifacts/net.neferett/webviewsinjector/
implementation 'net.neferett:webviewsinjector:2.1.6'
// https://jarcasting.com/artifacts/net.neferett/webviewsinjector/
implementation ("net.neferett:webviewsinjector:2.1.6")
'net.neferett:webviewsinjector:aar:2.1.6'
<dependency org="net.neferett" name="webviewsinjector" rev="2.1.6">
  <artifact name="webviewsinjector" type="aar" />
</dependency>
@Grapes(
@Grab(group='net.neferett', module='webviewsinjector', version='2.1.6')
)
libraryDependencies += "net.neferett" % "webviewsinjector" % "2.1.6"
[net.neferett/webviewsinjector "2.1.6"]

Dependencies

compile (2)

Group / Artifact Type Version
androidx.appcompat » appcompat jar 1.1.0
androidx.constraintlayout » constraintlayout jar 1.1.3

Project Modules

There are no modules declared in this project.

WebView AutoLogin and JavaScript asynchronous and synchronous injector

License: MPL 2.0 Maven Central GitHub release Codacy Badge

Auto Login System based on WebView and Generic LoginService

Current Services

Research Engine:

  • Google.com (Maps)

Travelling Websites:

  • Hotels.com
  • Booking.com
  • Expedia.com
  • Trainline
  • Agoda

Online Social Networks:

  • Twitter
  • Facebook
  • Instagram
  • Pinterest

Sports:

  • Strava.com

You can also:

  • Create any automated login service
  • Inject any JavaScript code inside WebViews

Installation

Install the dependency with Gradle (only authorised developers) inside your Main Application

    dependencies {
        implementation 'net.neferett:webviewsinjector:2.1.6'
    }

Don't forget to add maven central in your repositories:

    buildscript {
      repositories {
          google()
          jcenter()
          mavenCentral()
      }
    }

Add INTERNET permission to your android application

    <uses-permission android:name="android.permission.INTERNET" />

How to use it

Here's what you need to implement, to have an automated LoginService

    // Context should be your Main Activity of your application
    LoginService loginService = new GoogleService(context);
    // Email and Password should be clear string
    loginService.autoLogin(<email>, <password>, new ResponseCallback() {
        @Override
        public void getResponse(ResponseEnum responseEnum, String data) {
            if (responseEnum != ResponseEnum.SUCCESS) 
                // You can use responseEnum.getName() to get what went wrong and print it
            else 
                // User automatically authenticated
        }
    });

Create an automated LoginService

We have here created a LoginService instance, creating thus an automated login for a specified website.

    public class MyTestService extends LoginService {

        /**
         *
         * Step Enum can be ONE_STEP or TWO_STEP login
         * ONE_STEP is when email and password input are on the same page
         * TWO_STEP is when user have to click on next button
         *
         * Delay is how much time the bot should wait between entering inputs and clicking on buttons
         *
         * @param context Main Activity Context
         */
        public MyTestService(final Context context) {
            super(StepEnum.TWO_STEP, context, "https://mytestservice.com/login", 2, R.drawable.SERVICELOGO);
        }
    
        /**
         * We are here defining which method to use inside JavaScript code injector
         * and the identifier that we should use to find the class to fill input or to click on
         */
        @Override
        void setupElements() {
            /*
                We are here selecting javascript getElementById method with email-input identifier
                Resulting in: document.getElementById('email-input');
             */
            this.step.getStep().addElement(TypesAuthElement.USERNAME, new ElementValue(
                    "getElementById", "email-input", false
            ));
    
             /*
                We are here selecting javascript getElementsByName method with password identifier
                Because getElementsByName return and array we thus choose the first one
                Resulting in: document.getElementsByName('password')[0];
             */
            this.step.getStep().addElement(TypesAuthElement.PASSWORD, new ElementValue(
                    "getElementsByName", "password", true
            ));
    
             /*
                We are here selecting javascript querySelectorAll method with button_next_login identifier
                Because querySelectorAll return and array we thus choose the first one
                This action will be automatically a click action because of BUTTON type
                Resulting in: document.querySelectorAll('button_next_login')[0].click();
             */
            this.step.getStep().addElement(TypesAuthElement.BUTTON_LOGIN, new ElementValue(
                    "querySelectorAll", "button_next_login", true
            ));
    
             /*
                We are here selecting javascript querySelectorAll method with button_password identifier
                This action will be automatically a click action because of BUTTON type
                Resulting in: document.getElementById('button_password').click();
             */
            this.step.getStep().addElement(TypesAuthElement.BUTTON_PASSWORD, new ElementValue(
                    "getElementById", "button_password", false
            ));
        }
    
        /**
         *
         * We are here choosing how to handle Response with JavaScript code checker
         * 
         * @return ResponseEnum and JavaScript Linked Code
         */
        @Override
        protected HashMap<ResponseEnum, String> setupTests() {
            return new HashMap<ResponseEnum, String>(){{
                // Final url that our user will be on once logged
                put(ResponseEnum.FINISH_URL, "https://mytestservice.com/myaccount");
                
                // Here we are checking if class 'bad_email_icon' exists, if it does response will return BAD_EMAIL
                put(ResponseEnum.BAD_EMAIL, "document.getElementsByClassName('bad_email_icon')[0]");
                
                // Here we are checking the query 'bad_password span' exists, if it does response will return BAD_PASSWORD
                put(ResponseEnum.BAD_PASSWORD, "document.querySelector('.bad_password span')");
                
                // Here we are checking if class 'confirmation_email' exists, if it does, it means that user need to confirm his identity
                // Phone Number, email... Response will me set to CONFIRMATION_IDENTITY
                put(ResponseEnum.CONFIRMATION_IDENTITY, "document.getElementsByClassName('confirmation_email')[0]");
                
                // Here we are checking if id 'captcha' exists and if the user has to validate a captcha, response will be CAPTCHA
                put(ResponseEnum.CAPTCHA, "document.getElementById('captcha')[0]");
                
                // Finally, we are trying here to identify an element that only logged user can see meaning that user is authenticated
                // Response will be set to SUCCESS
                put(ResponseEnum.SUCCESS, "document.getElementsByClassName('email')[0]");
            }};
        }
    }

How to inject JavaScript code

We are here creating a WebView and injecting our JavaScript inside.

    // We are instantiating our main WebViewCreator Wrapper with our default settings
    WebViewCreator webViewCreator = new WebViewCreator(this, new HashMap<Settings, Boolean>(){{
        put(Settings.JavaScript, true);
        put(Settings.DomStorage, true);
        put(Settings.ClearCache, true);
    }});

    // We thus initialise our WebInjector, with our WebViewCreator instance and url that we want to inject code in
    WebInjector webInjector = new WebInjector(webViewCreator, "https://google.com");
    
    // We are here creating the WebView and loading url
    webInjector.load();
    
    // Finally we inject our code, the callback will be called only when the WebPage is fully loaded
    webInjector.inject("document.getElementsById('title')[0]", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String s) {
            // S is JavaScript response
        }
    });

You can also inject JavaScript inside a running webview, but we recommend to use our WebViewCreator

    WebInjector webInjector = new WebInjector(null, "https://google.com");

    webInjector.injectJavascript("document.getElementsById('title')[0]", <your_webview>, new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String s) {
            // S is JavaScript response
        }
    });

Moreover, you can use WebInjector to inject asynchronous JavaScript the callback will be called once the following javascript function is called:

    Injector.promiseReceive("Done")

JavaScript example:

    new Promise((res, err) => {
       setTimeout(res, 2000);
    }).then(() => Injector.promiseReceive("Done"));

Java example:

     WebInjector webInjector = new WebInjector(null, "https://google.com");
    
     webInjector.urlInjector("https://google.com/maps", "
        new Promise((res, err) => {
            setTimeout(res, 2000);
        }).then(() => Injector.promiseReceive("Done"));
    ", <your_webview>, new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String s) {
            // S is JavaScript response
        }
    });

PriVELT

Android application to centralise known data from different services. The project is funded by PriVELT (https://privelt.ac.uk/). The project is based on scraping and is only for researches purposes.

License

Mozilla Public License 2.0

Versions

Version
2.1.6
2.1.2
2.1.1
2.0.8
2.0.7
2.0.6
2.0.3
2.0.1
2.0.0