Skip to content

Commit

Permalink
merge: locker
Browse files Browse the repository at this point in the history
  • Loading branch information
Nguyen Thinh authored and Nguyen Thinh committed Mar 14, 2024
2 parents 2f4b177 + 44a0917 commit 78a4a4f
Show file tree
Hide file tree
Showing 111 changed files with 2,388 additions and 3,636 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@ public class AutofillDataKeychain {
private final CipherStorage cipherStorage;

// Data used by autofill service
public boolean faceIdEnabled = false;
public boolean loginedLocker = false;

public String email;
public String hashMassterPass;
public String userAvatar;
public ArrayList<AutofillItem> credentials = new ArrayList<>();
public String hashPass;
public String avatar;
public boolean faceIdEnabled = false;
public boolean isLoggedInPw = false;

public String language = "en";
public boolean isDarkTheme = false;

public ArrayList<AutofillItem> passwords = new ArrayList<>();
// public ArrayList<AutofillItem> otherCredentials = new ArrayList<>();


Expand All @@ -47,16 +52,17 @@ public AutofillDataKeychain(ReactApplicationContext reactContext) {
}

/**
* Deprecated
* For a given domain name, attempt to find matching AutoFill credentials
* @return - List of matching Username/Passwords in the form of the AutofillData class.
*/
public void getAutoFillEntriesForDomain() {
try {
String itemString = getAutoFillItems();
Log.d(TAG, itemString);
if (itemString == null){
return;
}
loginedLocker = true;
JSONObject jsonObject = new JSONObject(itemString);
JSONArray jsonArray = jsonObject.getJSONArray("passwords");
List<Object> itemList = toList(jsonArray);
Expand All @@ -69,18 +75,19 @@ public void getAutoFillEntriesForDomain() {
String name = (String) map.get("name");
String id = (String) map.get("id");

credentials.add(new AutofillItem(id, username, password, name, uri));
}
}
this.passwords.add(new AutofillItem(id, username, password, name, uri));
};
};
this.email = jsonObject.getString("email");
this.hashPass = jsonObject.getString("hashPass");
this.avatar = jsonObject.getString("avatar");
this.language = jsonObject.getString("language");
this.faceIdEnabled = jsonObject.getBoolean("faceIdEnabled");
this.isLoggedInPw = jsonObject.getBoolean("isLoggedInPw");
this.isDarkTheme = jsonObject.getBoolean("isDarkTheme");

JSONObject authen = jsonObject.getJSONObject("authen");
email = authen.getString("email");
hashMassterPass = authen.getString("hashPass");
userAvatar = authen.getString("avatar");
faceIdEnabled = jsonObject.getBoolean("faceIdEnabled");
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());

}
}
private String getAutoFillItems() throws Exception {
Expand All @@ -90,7 +97,6 @@ private String getAutoFillItems() throws Exception {
return "[]";
}


CipherStorage.DecryptionResult decryptionResult = cipherStorage.decrypt(service, resultSet.username, resultSet.password, SecurityLevel.ANY);
return decryptionResult.password;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,38 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.view.autofill.AutofillId;
import android.view.View;
import androidx.annotation.RequiresApi;

import java.io.Serializable;


@RequiresApi(api = Build.VERSION_CODES.O)
public class Field implements Parcelable {
public static final int FILL_TYPE_NONE = 0;
public static final int FILL_TYPE_EMAIL = 1;
public static final int FILL_TYPE_USERNAME = 2;
public static final int FILL_TYPE_PASSWORD = 3;
public static final int FILL_TYPE_UNKNOW= 4;

public int fillType = FILL_TYPE_NONE;
public AutofillId autofillId;
public String hint;
public String idHint;
public String[] hints;

public String idEntry;
public String entry;
public String text;

public int inputType;
public int autofillType;

public Field(AssistStructure.ViewNode node) {
this.autofillId = node.getAutofillId();
this.hint = node.getHint();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
this.idHint = node.getHintIdEntry();
}
this.entry = node.getIdEntry();
this.idEntry = node.getIdEntry();
if (node.getText() != null) {
this.text = node.getText().toString();
}
Expand All @@ -43,8 +49,10 @@ protected Field(Parcel in) {
fillType = in.readInt();
autofillId = in.readParcelable(AutofillId.class.getClassLoader());
hint = in.readString();
idHint = in.readString();
hints = in.createStringArray();
entry = in.readString();
idEntry = in.readString();
text = in.readString();
inputType = in.readInt();
autofillType = in.readInt();
Expand Down Expand Up @@ -72,8 +80,10 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(fillType);
dest.writeParcelable(autofillId, flags);
dest.writeString(hint);
dest.writeString(idHint);
dest.writeStringArray(hints);
dest.writeString(entry);
dest.writeString(idEntry);
dest.writeString(text);
dest.writeInt(inputType);
dest.writeInt(autofillType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

@RequiresApi(api = Build.VERSION_CODES.O)
public class LockerAutoFillService extends AutofillService {
private static final String TAG = "Locker_Service";
private static final String TAG = "LockerAutoFillService";
private boolean readyToStart = false;

@Override
Expand All @@ -36,9 +36,9 @@ public void onConnected() {

ReactApplicationContext reactContext = new ReactApplicationContext(getApplicationContext());
AutofillDataKeychain keyStore = new AutofillDataKeychain(reactContext);
if (keyStore.loginedLocker) {
if (keyStore.isLoggedInPw) {
this.readyToStart = true;
Utils.InitCredentialsStore(getBaseContext(), keyStore.email, keyStore.hashMassterPass);
Utils.InitCredentialsStore(getBaseContext(), keyStore.email, keyStore.hashPass);
} else {
Utils.RemoveAllCredential();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package com.cystack.locker.selfhost.autofill.parser;

import android.app.assist.AssistStructure;
import android.os.Build;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;


import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

Expand Down Expand Up @@ -36,39 +32,48 @@ public class FieldParser {
"tìm kiếm"
)
);
public HashSet<String> passwordTerms = new HashSet<String>(
private HashSet<String> passwordTerms = new HashSet<String>(
Arrays.asList("password",
"pswd",
"pw",
"pwd",
"mật Khẩu",
"pass",
"Mật "
)
);

public HashSet<String> usernameTerms = new HashSet<String>(
Arrays.asList("username",
"login",
"id",
"tên đăng nhập"
)
);
public HashSet<String> emailTerms = new HashSet<String>(
Arrays.asList("email",
"address"
)
);


@Nullable
public List<Field> getFillableItem(){
// add some heuristics
if (fillable.size() == 0) {
Log.d(TAG, "Not found any fill-able field");
return null;
}

if (fields.size() == 1) {
if (fields.get(0).fillType != Field.FILL_TYPE_PASSWORD) {
return null;
} else
return fields;
}

return parseLoginField(fillable);
return fillable;
}


public void addField(Field field){
if (field.autofillType != View.AUTOFILL_TYPE_NONE) {
fields.add(field);
}
}
public void parser() {
Log.d(TAG, "find fields size: " + fields.size());
List<Field> unknowType = new ArrayList<>();
for (Field field: fields){
// parse by hint
String hint = parseHint(field);
Expand All @@ -86,24 +91,44 @@ public void parser() {
}
fillable.add(field);
autofillIds.add(field.autofillId.toString());
}

// parse inputType
boolean isPasswordField = parseInputType(field);
if (isPasswordField){
if (!autofillIds.contains(field.autofillId.toString())){
field.fillType = Field.FILL_TYPE_PASSWORD;
fillable.add(field);
} else {
// parse inputType
boolean isPasswordField = parseInputType(field);
if (isPasswordField) {
if (!autofillIds.contains(field.autofillId.toString())) {
field.fillType = Field.FILL_TYPE_PASSWORD;
fillable.add(field);
}
} else {
field.fillType = Field.FILL_TYPE_UNKNOW;
unknowType.add(field);
}
}
}
Log.d(TAG, "unknowType fields size: " + unknowType.size());
// If there is only 1 fillable item in the list and the type is Fill.FILL_TYPE PASSWORD
// and if there is only 1 item in the list the type is unknown
// Then make item default type Field.FILL_TYPE_USERNAME;
if (fillable.size() == 1 && fillable.get(0).fillType == Field.FILL_TYPE_PASSWORD) {
if (unknowType.size() == 1) {
Field field = unknowType.get(0);
field.fillType = Field.FILL_TYPE_USERNAME;
fillable.add(field);
}
}
}

/**
* Analyze login patterns by finding username and password fields in the field list
* @param fields
* @return
*/
private List<Field> parseLoginField(List<Field> fields) {
int size = fields.size();
List<Field> loginField = new ArrayList<>();
for (int i = 0 ; i < size; i++ ){
int fillType = fields.get(i).fillType;
Log.d(TAG, "field type "+ fillType);
if (fillType == Field.FILL_TYPE_EMAIL || fillType == Field.FILL_TYPE_USERNAME) {
loginField.add(fields.get(i));
if ( i == size - 1) {
Expand All @@ -118,7 +143,7 @@ private List<Field> parseLoginField(List<Field> fields) {
}
}
}
return null;
return loginField;
}

private boolean parseInputType(Field field) {
Expand All @@ -128,11 +153,9 @@ private boolean parseInputType(Field field) {
if ((type & InputType.TYPE_TEXT_VARIATION_PASSWORD) == InputType.TYPE_TEXT_VARIATION_PASSWORD){
if ((type & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == InputType.TYPE_TEXT_FLAG_MULTI_LINE) {
inputTypePassword = false;

} else {
inputTypePassword = true;
}

}
if ((type & InputType.TYPE_NUMBER_VARIATION_PASSWORD) == InputType.TYPE_NUMBER_VARIATION_PASSWORD){
inputTypePassword = true;
Expand All @@ -144,7 +167,7 @@ private boolean parseInputType(Field field) {
inputTypePassword = true;
}

Log.d("pass field ", String.valueOf(inputTypePassword));
Log.d("inputTypePassword", String.valueOf(inputTypePassword));
return inputTypePassword && !valueContainsAnyTerms(field.hint, ignoreSearchTerms)
&& !valueContainsAnyTerms(field.entry, ignoreSearchTerms);
}
Expand All @@ -160,50 +183,30 @@ private String parseHint(Field field) {
if (hint != null) return hint;
}
}

// Then try some basic heuristics based on other node properties
// using hint
hint = inferHint(field.hint);
if (hint != null) {
return hint;
}

//using resourceId
hint = inferHint(field.entry);
if (hint != null) {
return hint;
}

// using text
hint = inferHint(field.text);
if (hint != null) {
return hint;
String[] moreHeuristics = new String[] {field.hint, field.idHint, field.entry, field.idEntry, field.text};
for (String fieldHint: moreHeuristics) {
hint = inferHint(fieldHint);
if (hint != null) return hint;
}
return null;
}



@Nullable
protected String inferHint(@Nullable String actualHint) {

if (actualHint == null) return null;
if (Utils.isNullOrWhiteSpace(actualHint)) return null;
Log.d(TAG, actualHint);
Log.d(TAG, "mật khẩu");
String hint = actualHint.toLowerCase();
if (hint.contains("label") || hint.contains("container")) {
return null;
}
if (hint.contains("password") || hint.contains("mật khẩu")) return View.AUTOFILL_HINT_PASSWORD;
if (hint.contains("username")
|| (hint.contains("login") && hint.contains("id")) || hint.contains("tên đăng nhập"))
if (valueContainsAnyTerms(hint, passwordTerms)) return View.AUTOFILL_HINT_PASSWORD;
if (valueContainsAnyTerms(hint, usernameTerms))
return View.AUTOFILL_HINT_USERNAME;
if (hint.contains("email")) return View.AUTOFILL_HINT_EMAIL_ADDRESS;
if (valueContainsAnyTerms(hint, emailTerms)) return View.AUTOFILL_HINT_EMAIL_ADDRESS;

return null;
}


private boolean valueContainsAnyTerms(String value, HashSet<String> terms)
{
if (Utils.isNullOrWhiteSpace(value))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public Result Parse() {

private void ParseNode(AssistStructure.ViewNode node){
setPackageAndDomain(node);

Log.d(TAG + "---", node.getClassName());
// First try the explicit autofill hints...
boolean haveAutofillHints = node.getAutofillHints() != null && node.getAutofillHints().length > 0;
boolean isEditText = node.getClassName() != null && (node.getClassName().contains("EditText") || node.getClassName().contains("AutoCompleteTextView"));
Expand Down
Loading

0 comments on commit 78a4a4f

Please sign in to comment.