diff --git a/metadata/com.standardnotes.yml b/metadata/com.standardnotes.yml index 4bf6b24a0a..8fca170c1e 100644 --- a/metadata/com.standardnotes.yml +++ b/metadata/com.standardnotes.yml @@ -10040,14 +10040,13 @@ Builds: - versionName: 3.151.3 versionCode: 3000897 - disable: play-services-fido commit: '@standardnotes/mobile@3.151.3' subdir: packages/mobile/android/app sudo: - apt-get update - apt-get install -y libsecret-1-dev build-essential - - curl -Lo node.tar.gz https://nodejs.org/download/release/v16.19.0/node-v16.19.0-linux-x64.tar.gz - - echo "23770ba26a52cb8fedd1096613bbc419b8a033d774a457d9024bb5a0159f3585 node.tar.gz" + - curl -Lo node.tar.gz https://nodejs.org/download/release/v16.20.0/node-v16.20.0-linux-x64.tar.gz + - echo "7abc0e558fa3b3c4cc0fd3c7fa5dbe61500ba7213f5e87ed560c65a733c6a5c4 node.tar.gz" | sha256sum -c - - tar xzf node.tar.gz --strip-components=1 -C /usr/local/ - npm install -g yarn @@ -10061,6 +10060,7 @@ Builds: - npm_config_build_from_source=true yarn patch: - remove-IAP.3.146.2.patch + - disable-gms-u2f-support.patch gradle: - prod rm: @@ -10091,7 +10091,7 @@ Builds: MaintainerNotes: | Override gradle wrappers to make them consistent before the upstream merges https://github.com/standardnotes/app/pull/2197. The overridden version 7.2 can't build this application. -AutoUpdateMode: None +AutoUpdateMode: Version @standardnotes/mobile@%v UpdateCheckMode: HTTP VercodeOperation: - 3000310 + %c diff --git a/metadata/com.standardnotes/disable-gms-u2f-support.patch b/metadata/com.standardnotes/disable-gms-u2f-support.patch new file mode 100644 index 0000000000..8a46fa1f88 --- /dev/null +++ b/metadata/com.standardnotes/disable-gms-u2f-support.patch @@ -0,0 +1,279 @@ +diff --git a/packages/mobile/android/app/build.gradle b/packages/mobile/android/app/build.gradle +index d37e75ae8..e98d60d16 100644 +--- a/packages/mobile/android/app/build.gradle ++++ b/packages/mobile/android/app/build.gradle +@@ -178,7 +178,6 @@ dependencies { + implementation 'androidx.appcompat:appcompat:1.1.0-rc01' + implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") + implementation 'de.undercouch:gradle-download-task:5.0.2' +- implementation 'com.google.android.gms:play-services-fido:20.0.1' + + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") + +diff --git a/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiModule.java b/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiModule.java +deleted file mode 100644 +index 124b110a1..000000000 +--- a/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiModule.java ++++ /dev/null +@@ -1,204 +0,0 @@ +-package com.standardnotes; +- +-import android.app.Activity; +-import android.app.PendingIntent; +-import android.content.Intent; +-import android.content.IntentSender; +-import android.util.Base64; +-import android.util.Log; +-import com.facebook.react.bridge.Arguments; +-import com.facebook.react.bridge.NativeModule; +-import com.facebook.react.bridge.ReactApplicationContext; +-import com.facebook.react.bridge.ActivityEventListener; +-import com.facebook.react.bridge.BaseActivityEventListener; +-import com.facebook.react.bridge.ReactContext; +-import com.facebook.react.bridge.ReactContextBaseJavaModule; +-import com.facebook.react.bridge.ReactMethod; +-import com.facebook.react.bridge.Promise; +-import com.facebook.react.bridge.WritableMap; +-import java.util.Map; +-import java.util.HashMap; +-import java.util.ArrayList; +- +-import org.json.JSONObject; +-import org.json.JSONArray; +-import org.json.JSONException; +- +-import com.google.android.gms.fido.fido2.Fido2ApiClient; +-import com.google.android.gms.fido.fido2.api.common.AuthenticatorErrorResponse; +-import com.google.android.gms.fido.fido2.api.common.AuthenticatorAssertionResponse; +-import com.google.android.gms.fido.fido2.api.common.AuthenticationExtensionsClientOutputs; +-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential; +-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialType; +-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialDescriptor; +-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions; +-import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions; +-import com.google.android.gms.fido.Fido; +-import com.google.android.gms.tasks.OnFailureListener; +-import com.google.android.gms.tasks.OnSuccessListener; +-import com.google.android.gms.tasks.Task; +- +-public class Fido2ApiModule extends ReactContextBaseJavaModule { +- private final Fido2ApiClient fido2ApiClient; +- private final ReactApplicationContext reactContext; +- private static final int SIGN_REQUEST_CODE = 111; +- +- private static final String LOGS_TAG = "Fido2ApiModule"; +- private static final String RP_ID = "app.standardnotes.com"; +- +- private Promise signInPromise; +- +- private final ActivityEventListener activityEventListener = new BaseActivityEventListener() { +- @Override +- public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) { +- super.onActivityResult(activity, requestCode, resultCode, intent); +- +- if (requestCode == SIGN_REQUEST_CODE) { +- if (signInPromise != null) { +- if (resultCode == Activity.RESULT_CANCELED) { +- Log.e(LOGS_TAG, "FIDO sign in cancelled"); +- +- signInPromise.reject("FIDO sign in cancelled"); +- } else if (resultCode == Activity.RESULT_OK) { +- if (intent.hasExtra(Fido.FIDO2_KEY_ERROR_EXTRA)) { +- AuthenticatorErrorResponse authenticatorErrorResponse = +- AuthenticatorErrorResponse.deserializeFromBytes(intent.getByteArrayExtra(Fido.FIDO2_KEY_ERROR_EXTRA)); +- Log.e(LOGS_TAG, "Fido Error: " + authenticatorErrorResponse.getErrorMessage()); +- +- signInPromise.reject(authenticatorErrorResponse.getErrorMessage()); +- } else if (intent.hasExtra(Fido.FIDO2_KEY_CREDENTIAL_EXTRA)) { +- PublicKeyCredential publicKeyCredential = +- PublicKeyCredential.deserializeFromBytes( +- intent.getByteArrayExtra(Fido.FIDO2_KEY_CREDENTIAL_EXTRA)); +- AuthenticatorAssertionResponse signedData = +- (AuthenticatorAssertionResponse) publicKeyCredential.getResponse(); +- +- WritableMap signInResult = Arguments.createMap(); +- signInResult.putString("id", Base64.encodeToString(signedData.getKeyHandle(), Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- signInResult.putString("rawId", Base64.encodeToString(signedData.getKeyHandle(), Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- +- byte[] extensionOutputsBytes = null; +- AuthenticationExtensionsClientOutputs extensionOutputs = publicKeyCredential.getClientExtensionResults(); +- if (extensionOutputs != null) { +- extensionOutputsBytes = extensionOutputs.serializeToBytes(); +- if (extensionOutputsBytes != null) { +- signInResult.putString("clientExtensionResults", Base64.encodeToString(extensionOutputsBytes, Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- } +- } +- +- WritableMap response = Arguments.createMap(); +- response.putString("clientDataJSON", Base64.encodeToString(signedData.getClientDataJSON(), Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- response.putString("authenticatorData", Base64.encodeToString(signedData.getAuthenticatorData(), Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- response.putString("signature", Base64.encodeToString(signedData.getSignature(), Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- byte[] userHandle = signedData.getUserHandle(); +- if (userHandle != null) { +- response.putString("userHandle", Base64.encodeToString(userHandle, Base64.URL_SAFE + Base64.NO_WRAP + Base64.NO_PADDING)); +- } +- signInResult.putMap("response", response); +- signInResult.putString("type", PublicKeyCredentialType.PUBLIC_KEY.toString()); +- +- signInPromise.resolve(signInResult); +- } +- } +- } +- signInPromise = null; +- } +- } +- }; +- +- Fido2ApiModule(ReactApplicationContext context) { +- super(context); +- +- fido2ApiClient = Fido.getFido2ApiClient(context); +- context.addActivityEventListener(activityEventListener); +- +- this.reactContext = context; +- } +- +- @Override +- public String getName() { +- return "Fido2ApiModule"; +- } +- +- @ReactMethod +- public void promptForU2FAuthentication(String authenticationOptionsJSONString, Promise promise) throws JSONException { +- signInPromise = promise; +- +- JSONObject authenticationOptions = new JSONObject(authenticationOptionsJSONString); +- +- ArrayList allowedKeys = new ArrayList(); +- +- JSONArray allowedCredentials = authenticationOptions.getJSONArray("allowCredentials"); +- for (int i = 0, size = allowedCredentials.length(); i < size; i++) { +- JSONObject allowedCredential = allowedCredentials.getJSONObject(i); +- allowedKeys.add( +- new PublicKeyCredentialDescriptor( +- PublicKeyCredentialType.PUBLIC_KEY.toString(), +- this.convertBase64URLStringToBytes(allowedCredential.getString("id")), +- null +- ) +- ); +- } +- +- String challenge = authenticationOptions.getString("challenge"); +- Double timeout = authenticationOptions.getDouble("timeout") / 1000d; +- +- PublicKeyCredentialRequestOptions.Builder optionsBuilder = new PublicKeyCredentialRequestOptions +- .Builder() +- .setRpId(RP_ID) +- .setAllowList(allowedKeys) +- .setChallenge(this.convertBase64URLStringToBytes(challenge)) +- .setTimeoutSeconds(timeout); +- +- PublicKeyCredentialRequestOptions options = optionsBuilder.build(); +- +- Task result = this.fido2ApiClient.getSignPendingIntent(options); +- +- final Activity activity = this.reactContext.getCurrentActivity(); +- +- result.addOnSuccessListener( +- new OnSuccessListener() { +- @Override +- public void onSuccess(PendingIntent fido2PendingIntent) { +- if (fido2PendingIntent == null) { +- Log.e(LOGS_TAG, "No pending FIDO intent returned"); +- return; +- } +- +- try { +- activity.startIntentSenderForResult( +- fido2PendingIntent.getIntentSender(), +- SIGN_REQUEST_CODE, +- null, +- 0, +- 0, +- 0 +- ); +- } catch (IntentSender.SendIntentException exception) { +- Log.e(LOGS_TAG, "Error starting FIDO intent: " + exception.getMessage()); +- } +- } +- } +- ); +- +- result.addOnFailureListener( +- new OnFailureListener() { +- @Override +- public void onFailure(Exception e) { +- Log.e(LOGS_TAG, "Error getting FIDO intent: " + e.getMessage()); +- signInPromise.reject(e.getMessage()); +- } +- } +- ); +- } +- +- private byte[] convertBase64URLStringToBytes(String base64URLString) { +- String base64String = base64URLString.replace('-', '+').replace('_', '/'); +- int padding = (4 - (base64String.length() % 4)) % 4; +- for (int i = 0; i < padding; i++) { +- base64String += '='; +- } +- +- return Base64.decode(base64String, Base64.DEFAULT); +- } +-} +diff --git a/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiPackage.java b/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiPackage.java +deleted file mode 100644 +index fdc54a46b..000000000 +--- a/packages/mobile/android/app/src/main/java/com/standardnotes/Fido2ApiPackage.java ++++ /dev/null +@@ -1,26 +0,0 @@ +-package com.standardnotes; +- +-import com.facebook.react.ReactPackage; +-import com.facebook.react.bridge.NativeModule; +-import com.facebook.react.bridge.ReactApplicationContext; +-import com.facebook.react.uimanager.ViewManager; +- +-import java.util.ArrayList; +-import java.util.Collections; +-import java.util.List; +- +-public class Fido2ApiPackage implements ReactPackage { +- @Override +- public List createViewManagers(ReactApplicationContext reactContext) { +- return Collections.emptyList(); +- } +- +- @Override +- public List createNativeModules(ReactApplicationContext reactContext) { +- List modules = new ArrayList<>(); +- +- modules.add(new Fido2ApiModule(reactContext)); +- +- return modules; +- } +-} +diff --git a/packages/mobile/android/app/src/main/java/com/standardnotes/MainApplication.java b/packages/mobile/android/app/src/main/java/com/standardnotes/MainApplication.java +index fd6570cc7..e38bb9759 100644 +--- a/packages/mobile/android/app/src/main/java/com/standardnotes/MainApplication.java ++++ b/packages/mobile/android/app/src/main/java/com/standardnotes/MainApplication.java +@@ -37,7 +37,6 @@ public class MainApplication extends Application implements ReactApplication { + @SuppressWarnings("UnnecessaryLocalVariable") + List packages = new PackageList(this).getPackages(); + +- packages.add(new Fido2ApiPackage()); + + return packages; + } +diff --git a/packages/web/src/javascripts/Components/ChallengeModal/U2FPrompt.tsx b/packages/web/src/javascripts/Components/ChallengeModal/U2FPrompt.tsx +index c74c9ee71..750e54ab9 100644 +--- a/packages/web/src/javascripts/Components/ChallengeModal/U2FPrompt.tsx ++++ b/packages/web/src/javascripts/Components/ChallengeModal/U2FPrompt.tsx +@@ -23,7 +23,7 @@ const U2FPrompt = ({ application, onValueChange, prompt, buttonRef, contextData + const [authenticatorResponse, setAuthenticatorResponse] = useState | null>(null) + const [error, setError] = useState('') + +- if (!application.isFullU2FClient && !isAndroid()) { ++ if (!application.isFullU2FClient) { + return ( +