From 0072eaaab02f41ea007efd52b8699d9040fd3321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sat, 28 Nov 2020 03:32:39 +0800 Subject: [PATCH] Allow login with qr & Refine its scan --- TMessagesProj/build.gradle | 4 +- TMessagesProj/jni/TgNetWrapper.cpp | 7 + TMessagesProj/jni/tgnet/ConnectionsManager.h | 3 +- .../languages/unofficial_base_moecn.xml | 2 +- .../org/telegram/messenger/BuildVars.java | 2 +- .../messenger/MessagesController.java | 7 + .../messenger/NotificationCenter.java | 2 + .../telegram/tgnet/ConnectionsManager.java | 2 + .../telegram/ui/ActionBar/AlertDialog.java | 2 +- .../org/telegram/ui/CameraScanActivity.java | 49 ++++--- .../java/org/telegram/ui/LaunchActivity.java | 50 ++++++- .../java/org/telegram/ui/LoginActivity.java | 133 ++++++++++++++++++ .../org/telegram/ui/SessionsActivity.java | 6 + .../java/tw/nekomimi/nekogram/NekoConfig.java | 2 +- .../tw/nekomimi/nekogram/utils/ProxyUtil.kt | 35 ++--- .../src/main/res/values/strings_nekox.xml | 4 +- 16 files changed, 256 insertions(+), 54 deletions(-) diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index bf65add42..45721534e 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -1,8 +1,8 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -def verName = "7.2.1" -def verCode = 117 +def verName = "7.2.1.1" +def verCode = 118 def serviceAccountCredentialsFile = rootProject.file("service_account_credentials.json") diff --git a/TMessagesProj/jni/TgNetWrapper.cpp b/TMessagesProj/jni/TgNetWrapper.cpp index 737dfe9c4..e80fdd9ea 100644 --- a/TMessagesProj/jni/TgNetWrapper.cpp +++ b/TMessagesProj/jni/TgNetWrapper.cpp @@ -195,6 +195,12 @@ void setLayer(JNIEnv *env, jclass c, jint instanceNum, jint layer) { } +void moveToDatacenter(JNIEnv *env, jclass c, jint instanceNum, jint datacenterId) { + + ConnectionsManager::getInstance(instanceNum).moveToDatacenter((uint32_t) datacenterId); + +} + void saveDatacenters(JNIEnv *env, jclass c,jint instanceNum) { ConnectionsManager::getInstance(instanceNum).saveDatacenters(); @@ -478,6 +484,7 @@ static JNINativeMethod ConnectionsManagerMethods[] = { {"native_setDatacenterAddress", "(IILjava/lang/String;Ljava/lang/String;I)V", (void *) setDatacenterAddress}, {"native_saveDatacenters", "(I)V", (void *) saveDatacenters}, {"native_setLayer", "(II)V", (void *) setLayer}, + {"native_moveToDatacenter", "(II)V", (void *) moveToDatacenter}, {"native_setProxySettings", "(ILjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", (void *) setProxySettings}, {"native_getConnectionState", "(I)I", (void *) getConnectionState}, {"native_setUserId", "(II)V", (void *) setUserId}, diff --git a/TMessagesProj/jni/tgnet/ConnectionsManager.h b/TMessagesProj/jni/tgnet/ConnectionsManager.h index 7aefaa285..1683bc28e 100644 --- a/TMessagesProj/jni/tgnet/ConnectionsManager.h +++ b/TMessagesProj/jni/tgnet/ConnectionsManager.h @@ -76,6 +76,8 @@ public: void setPushConnectionEnabled(bool value); void applyDnsConfig(NativeByteBuffer *buffer, std::string phone, int32_t date); void setMtProtoVersion(int version); + void moveToDatacenter(uint32_t datacenterId); + int32_t getMtProtoVersion(); int64_t checkProxy(std::string address, uint16_t port, std::string username, std::string password, std::string secret, onRequestTimeFunc requestTimeFunc, jobject ptr1); @@ -101,7 +103,6 @@ private: void clearRequestsForDatacenter(Datacenter *datacenter, HandshakeType type); void registerForInternalPushUpdates(); void processRequestQueue(uint32_t connectionType, uint32_t datacenterId); - void moveToDatacenter(uint32_t datacenterId); void authorizeOnMovingDatacenter(); void authorizedOnMovingDatacenter(); Datacenter *getDatacenterWithId(uint32_t datacenterId); diff --git a/TMessagesProj/src/main/assets/languages/unofficial_base_moecn.xml b/TMessagesProj/src/main/assets/languages/unofficial_base_moecn.xml index 7c0539195..015a033c4 100644 --- a/TMessagesProj/src/main/assets/languages/unofficial_base_moecn.xml +++ b/TMessagesProj/src/main/assets/languages/unofficial_base_moecn.xml @@ -2189,7 +2189,7 @@ Telegram 团队 此操作是不可逆的。超级群组不可能降级为普通群组。 un1 删除了这条消息: 千米以外 -通过二维码登录 +通过二维码登录 视频消息 %1$s 给您发送了一个 %2$s 表情 %1$s 已移动到您的归档中。 diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 40c0b3585..2f7268b81 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -16,7 +16,7 @@ import android.content.pm.PackageManager; @SuppressWarnings("ConstantConditions") public class BuildVars { - public static boolean DEBUG_VERSION = BuildConfig.BUILD_TYPE.equals("debug") || BuildConfig.VERSION_NAME.contains("preview"); + public static boolean DEBUG_VERSION = BuildConfig.BUILD_TYPE.equals("debug"); public static boolean DEBUG_PRIVATE_VERSION = DEBUG_VERSION; public static boolean LOGS_ENABLED; public static boolean USE_CLOUD_STRINGS = true; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index f8510dd84..ffdc1bc8a 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -12144,6 +12144,11 @@ public class MessagesController extends BaseController implements NotificationCe updatesOnMainThread = new ArrayList<>(); } updatesOnMainThread.add(baseUpdate); + } else if (baseUpdate instanceof TLRPC.TL_updateLoginToken) { + if (updatesOnMainThread == null) { + updatesOnMainThread = new ArrayList<>(); + } + updatesOnMainThread.add(baseUpdate); } } if (messages != null) { @@ -12688,6 +12693,8 @@ public class MessagesController extends BaseController implements NotificationCe } else if (baseUpdate instanceof TLRPC.TL_updateReadChannelDiscussionOutbox) { TLRPC.TL_updateReadChannelDiscussionOutbox update = (TLRPC.TL_updateReadChannelDiscussionOutbox) baseUpdate; getNotificationCenter().postNotificationName(NotificationCenter.threadMessagesRead, (long) -update.channel_id, update.top_msg_id, 0, update.read_max_id); + } else if (baseUpdate instanceof TLRPC.TL_updateLoginToken) { + getNotificationCenter().postNotificationName(NotificationCenter.updateLoginToken); } } if (editor != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java index da66fcbe2..2e011f379 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java @@ -204,6 +204,8 @@ public class NotificationCenter { // custom public static final int updateUserStatus = totalEvents++; + public static final int updateLoginToken = totalEvents++; + private SparseArray> observers = new SparseArray<>(); private SparseArray> removeAfterBroadcast = new SparseArray<>(); diff --git a/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java index df2e20c63..202791712 100644 --- a/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/tgnet/ConnectionsManager.java @@ -690,6 +690,8 @@ public class ConnectionsManager extends BaseController { public static native void native_setLayer(int currentAccount, int layer); + public static native void native_moveToDatacenter(int currentAccount, int datacenterId); + public static native int native_getConnectionState(int currentAccount); public static native void native_setUserId(int currentAccount, int id); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java index d8a9ee13d..0631cac87 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ActionBar/AlertDialog.java @@ -1137,7 +1137,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback { } public Builder setMessage(CharSequence message) { - alertDialog.message = message; + alertDialog.message = message instanceof String ? AndroidUtilities.replaceTags((String) message) : message; return this; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CameraScanActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CameraScanActivity.java index e48d34992..1ef78505b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CameraScanActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CameraScanActivity.java @@ -13,7 +13,6 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.ImageFormat; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; @@ -25,7 +24,6 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.text.TextUtils; -import android.util.SparseArray; import android.util.TypedValue; import android.view.Gravity; import android.view.View; @@ -35,14 +33,15 @@ import android.widget.TextView; import com.google.zxing.BinaryBitmap; import com.google.zxing.LuminanceSource; +import com.google.zxing.NotFoundException; import com.google.zxing.PlanarYUVLuminanceSource; import com.google.zxing.RGBLuminanceSource; import com.google.zxing.Result; import com.google.zxing.common.GlobalHistogramBinarizer; +import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; import org.telegram.messenger.AndroidUtilities; -import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.FileLog; import org.telegram.messenger.ImageLoader; import org.telegram.messenger.LocaleController; @@ -63,7 +62,6 @@ import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.LayoutHelper; -import java.nio.ByteBuffer; import java.util.ArrayList; @TargetApi(18) @@ -89,7 +87,7 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa //private BarcodeDetector visionQrReader; private boolean needGalleryButton; - private boolean any; + private boolean any; private int currentType; @@ -664,21 +662,27 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa text = null; } } else {*/ - LuminanceSource source; - if (bitmap != null) { - int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()]; - bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); - source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray); - } else { - source = new PlanarYUVLuminanceSource(data, size.getWidth(), size.getHeight(), x, y, side, side, false); - } - - Result result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source))); - if (result == null) { - onNoQrFound(); - return null; - } - text = result.getText(); + LuminanceSource source; + if (bitmap != null) { + int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()]; + bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()); + source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray); + } else { + source = new PlanarYUVLuminanceSource(data, size.getWidth(), size.getHeight(), x, y, side, side, false); + } + Result result = null; + try { + result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source))); + } catch (NotFoundException e) { + try { + result = qrReader.decode(new BinaryBitmap(new GlobalHistogramBinarizer(source.invert()))); + } catch (NotFoundException ignore) {} + } + if (result == null) { + onNoQrFound(); + return null; + } + text = result.getText(); //} if (TextUtils.isEmpty(text)) { onNoQrFound(); @@ -692,11 +696,6 @@ public class CameraScanActivity extends BaseFragment implements Camera.PreviewCa } Uri uri = Uri.parse(text); String path = uri.getPath().replace("/", ""); - } else { - if (!text.startsWith("tg://login?token=")) { - onNoQrFound(); - return null; - } } return text; } catch (Throwable ignore) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index 5a54df310..a1fad41e5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -32,6 +32,7 @@ import android.os.Parcelable; import android.os.StatFs; import android.os.SystemClock; import android.provider.ContactsContract; +import android.se.omapi.Session; import android.text.TextUtils; import android.util.Base64; import android.view.ActionMode; @@ -119,6 +120,7 @@ import org.telegram.ui.Components.StickersAlert; import org.telegram.ui.Components.Switch; import org.telegram.ui.Components.TermsOfServiceView; import org.telegram.ui.Components.ThemeEditorView; +import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.voip.VoIPHelper; import java.io.File; @@ -129,7 +131,9 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import kotlin.Unit; import kotlin.text.StringsKt; +import tw.nekomimi.nekogram.BottomBuilder; import tw.nekomimi.nekogram.ExternalGcm; import tw.nekomimi.nekogram.NekoConfig; import tw.nekomimi.nekogram.NekoXConfig; @@ -2472,11 +2476,47 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa } return; } else if (loginToken != null) { - AlertDialog.Builder builder = new AlertDialog.Builder(LaunchActivity.this); - builder.setTitle(LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient)); - builder.setMessage(LocaleController.getString("AuthAnotherClientUrl", R.string.AuthAnotherClientUrl)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null); - showAlertDialog(builder); + BottomBuilder builder = new BottomBuilder(this); + builder.addTitle(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan), LocaleController.getString("QRLoginNotice",R.string.QRLoginNotice)); + builder.addItem(LocaleController.getString("QRLoginConfirm", R.string.QRLoginConfirm), R.drawable.baseline_security_24, true, (c) -> { + AlertDialog progressDialog = new AlertDialog(this, 3); + progressDialog.setCanCacnel(false); + progressDialog.show(); + byte[] token = Base64.decode(loginToken, Base64.URL_SAFE); + TLRPC.TL_auth_acceptLoginToken req = new TLRPC.TL_auth_acceptLoginToken(); + req.token = token; + ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + try { + progressDialog.dismiss(); + } catch (Exception ignore) { + } + if (response instanceof TLRPC.TL_authorization) { + SessionsActivity fragment = new SessionsActivity(0); + fragment.newAuthorizationToOpen = (TLRPC.TL_authorization) response; + presentFragment(fragment, false, false); + if (AndroidUtilities.isTablet()) { + actionBarLayout.showLastFragment(); + rightActionBarLayout.showLastFragment(); + drawerLayoutContainer.setAllowOpenDrawer(false, false); + } else { + drawerLayoutContainer.setAllowOpenDrawer(true, false); + } + } else { + AndroidUtilities.runOnUIThread(() -> { + final String text; + if (error.text.equals("AUTH_TOKEN_EXCEPTION")) { + text = LocaleController.getString("AccountAlreadyLoggedIn", R.string.AccountAlreadyLoggedIn); + } else { + text = LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + error.text; + } + AlertUtil.showSimpleAlert(this, LocaleController.getString("AuthAnotherClient", R.string.AuthAnotherClient), text); + }); + } + })); + return Unit.INSTANCE; + }); + builder.addCancelItem(); + builder.show(); return; } final AlertDialog progressDialog = new AlertDialog(this, 3); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index e92b10d89..4af8118a9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -135,6 +135,7 @@ import tw.nekomimi.nekogram.EditTextAutoFill; import tw.nekomimi.nekogram.NekoXConfig; import tw.nekomimi.nekogram.parts.PKCS1Pub; import tw.nekomimi.nekogram.utils.AlertUtil; +import tw.nekomimi.nekogram.utils.ProxyUtil; import tw.nekomimi.nekogram.utils.VibrateUtil; @SuppressLint("HardwareIds") @@ -277,6 +278,11 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No private int menu_other = 5; private int menu_custom_api = 6; private int menu_custom_dc = 7; + private int menu_qr_login = 8; + + TLRPC.TL_auth_exportLoginToken exportLoginTokenRequest = null; + AlertDialog exportLoginTokenProgress = null; + android.app.AlertDialog exportLoginTokenDialog = null; @Override public View createView(Context context) { @@ -899,6 +905,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No }); builder.show(); + } else if (id == menu_qr_login) { + regenerateLoginToken(false); } } @@ -922,6 +930,7 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No Locale current = ConfigurationCompat.getLocales(getParentActivity().getResources().getConfiguration()).get(0); otherItem.addSubItem(4, R.drawable.list_bot, LocaleController.getString("BotLogin", R.string.BotLogin)); + otherItem.addSubItem(menu_qr_login, R.drawable.wallet_qr, LocaleController.getString("ImportLogin", R.string.ImportLogin)); otherItem.addSubItem(menu_custom_api, R.drawable.baseline_vpn_key_24, LocaleController.getString("CustomApi", R.string.CustomApi)); otherItem.addSubItem(menu_custom_dc, R.drawable.baseline_sync_24, LocaleController.getString("CustomBackend", R.string.CustomBackend)); @@ -1080,6 +1089,128 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No return fragmentView; } + private void regenerateLoginToken(Boolean refresh) { + + getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken); + + if (getParentActivity() == null || isFinished) return; + + if (exportLoginTokenDialog != null && exportLoginTokenDialog.isShowing()) { + exportLoginTokenDialog.dismiss(); + } else if (refresh) return; + + exportLoginTokenProgress = new AlertDialog(getParentActivity(), 3); + exportLoginTokenProgress.setCanCacnel(false); + exportLoginTokenProgress.show(); + + if (exportLoginTokenRequest == null) { + exportLoginTokenRequest = new TLRPC.TL_auth_exportLoginToken(); + exportLoginTokenRequest.api_id = NekoXConfig.currentAppId(); + exportLoginTokenRequest.api_hash = NekoXConfig.currentAppHash(); + exportLoginTokenRequest.except_ids = new ArrayList<>(); + for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) { + UserConfig userConfig = UserConfig.getInstance(a); + if (!userConfig.isClientActivated()) { + continue; + } + exportLoginTokenRequest.except_ids.add(a); + } + } + + getNotificationCenter().addObserver(this, NotificationCenter.updateLoginToken); + + getConnectionsManager().sendRequest(exportLoginTokenRequest, (response, error) -> AndroidUtilities.runOnUIThread(() -> { + if (getParentActivity() == null) return; + + try { + exportLoginTokenProgress.dismiss(); + } catch (Exception ignore) { + } + if (response instanceof TLRPC.TL_auth_loginToken) { + exportLoginTokenDialog = ProxyUtil.showQrDialog(getParentActivity(), "tg://login?token=" + Base64.encodeUrlSafe(((TLRPC.TL_auth_loginToken) response).token)); + int delay = (int) (((TLRPC.TL_auth_loginToken) response).expires - System.currentTimeMillis() / 1000); + if (BuildVars.DEBUG_VERSION) { + AlertUtil.showToast("Refresh after " + delay + "s"); + } + AndroidUtilities.runOnUIThread(() -> regenerateLoginToken(true), ((TLRPC.TL_auth_loginToken) response).expires * 1000L - System.currentTimeMillis()); + } else if (response instanceof TLRPC.TL_auth_loginTokenMigrateTo) { + checkMigrateTo((TLRPC.TL_auth_loginTokenMigrateTo) response); + } else if (response instanceof TLRPC.TL_auth_loginTokenSuccess) { + processLoginByTokenFinish((TLRPC.TL_auth_loginTokenSuccess) response); + } else { + if (error.text.contains("SESSION_PASSWORD_NEEDED")) { + exportLoginTokenProgress.show(); + TLRPC.TL_account_getPassword req2 = new TLRPC.TL_account_getPassword(); + ConnectionsManager.getInstance(currentAccount).sendRequest(req2, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> { + exportLoginTokenProgress.dismiss(); + showDoneButton(false, true); + if (error1 == null) { + TLRPC.TL_account_password password = (TLRPC.TL_account_password) response1; + if (!TwoStepVerificationActivity.canHandleCurrentPassword(password, true)) { + AlertsCreator.showUpdateAppAlert(getParentActivity(), LocaleController.getString("UpdateAppAlert", R.string.UpdateAppAlert), true); + return; + } + Bundle bundle = new Bundle(); + if (password.current_algo instanceof TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) { + TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow algo = (TLRPC.TL_passwordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow) password.current_algo; + bundle.putString("current_salt1", Utilities.bytesToHex(algo.salt1)); + bundle.putString("current_salt2", Utilities.bytesToHex(algo.salt2)); + bundle.putString("current_p", Utilities.bytesToHex(algo.p)); + bundle.putInt("current_g", algo.g); + bundle.putString("current_srp_B", Utilities.bytesToHex(password.srp_B)); + bundle.putLong("current_srp_id", password.srp_id); + bundle.putInt("passwordType", 1); + } + bundle.putString("hint", password.hint != null ? password.hint : ""); + bundle.putString("email_unconfirmed_pattern", password.email_unconfirmed_pattern != null ? password.email_unconfirmed_pattern : ""); + bundle.putInt("has_recovery", password.has_recovery ? 1 : 0); + setPage(6, true, bundle, false); + } else { + needShowAlert(LocaleController.getString("NekoX", R.string.NekoX), error1.text); + } + }), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin); + } else { + AlertUtil.showToast(error); + } + } + }), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin | ConnectionsManager.RequestFlagTryDifferentDc | ConnectionsManager.RequestFlagEnableUnauthorized); + + } + + private void checkMigrateTo(TLRPC.TL_auth_loginTokenMigrateTo response) { + getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken); + ConnectionsManager.native_moveToDatacenter(currentAccount, response.dc_id); + exportLoginTokenProgress.show(); + + TLRPC.TL_auth_importLoginToken request = new TLRPC.TL_auth_importLoginToken(); + request.token = response.token; + getConnectionsManager().sendRequest(request, (response1, error1) -> AndroidUtilities.runOnUIThread(() -> { + exportLoginTokenProgress.dismiss(); + if (error1 != null) { + exportLoginTokenRequest = null; + regenerateLoginToken(false); + } else if (response1 instanceof TLRPC.TL_auth_loginTokenSuccess) { + processLoginByTokenFinish((TLRPC.TL_auth_loginTokenSuccess) response1); + } + }), ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagWithoutLogin | ConnectionsManager.RequestFlagTryDifferentDc | ConnectionsManager.RequestFlagEnableUnauthorized); + + } + + private void processLoginByTokenFinish(TLRPC.TL_auth_loginTokenSuccess authLoginTokenSuccess) { + getNotificationCenter().removeObserver(this, NotificationCenter.updateLoginToken); + + TLRPC.auth_Authorization authorization = authLoginTokenSuccess.authorization; + if (authorization instanceof TLRPC.TL_auth_authorizationSignUpRequired) { + TLRPC.TL_auth_authorizationSignUpRequired authorizationI = (TLRPC.TL_auth_authorizationSignUpRequired) authorization; + if (authorizationI.terms_of_service != null) { + currentTermsOfService = authorizationI.terms_of_service; + } + setPage(5, true, new Bundle(), false); + } else { + onAuthSuccess((TLRPC.TL_auth_authorization) authorization); + } + } + private int currentConnectionState; @Override @@ -1090,6 +1221,8 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No currentConnectionState = state; updateProxyButton(true); } + } else if (id == NotificationCenter.updateLoginToken) { + regenerateLoginToken(false); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java index 9ebfdd1ab..360531fb7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SessionsActivity.java @@ -112,6 +112,8 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.newSessionReceived); } + TLRPC.TL_authorization newAuthorizationToOpen; + @Override public View createView(Context context) { actionBar.setBackButtonImage(R.drawable.ic_ab_back); @@ -421,6 +423,10 @@ public class SessionsActivity extends BaseFragment implements NotificationCenter frameLayout.addView(undoView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8)); } + if (newAuthorizationToOpen != null) { + AndroidUtilities.runOnUIThread(() -> undoView.showWithAction(0, UndoView.ACTION_QR_SESSION_ACCEPTED, newAuthorizationToOpen), 3000L); + } + return fragmentView; } diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java index 99fa1c47f..69c8ba294 100644 --- a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/NekoConfig.java @@ -247,7 +247,7 @@ public class NekoConfig { mediaPreview = preferences.getBoolean("mediaPreview", false); proxyAutoSwitch = preferences.getBoolean("proxy_auto_switch", false); - usePersianCalender = preferences.getBoolean("usePersianCalender", false); + usePersianCalender = false;//preferences.getBoolean("usePersianCalender", false); openPGPApp = preferences.getString("openPGPApp",""); openPGPKeyId = preferences.getLong("openPGPKeyId",0L); diff --git a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/utils/ProxyUtil.kt b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/utils/ProxyUtil.kt index 7348df30a..d246d9d92 100644 --- a/TMessagesProj/src/main/java/tw/nekomimi/nekogram/utils/ProxyUtil.kt +++ b/TMessagesProj/src/main/java/tw/nekomimi/nekogram/utils/ProxyUtil.kt @@ -2,6 +2,7 @@ package tw.nekomimi.nekogram.utils import android.Manifest import android.app.Activity +import android.app.AlertDialog import android.content.ClipboardManager import android.content.Context import android.content.ContextWrapper @@ -349,13 +350,13 @@ object ProxyUtil { } @JvmStatic - fun showQrDialog(ctx: Context, text: String) { + fun showQrDialog(ctx: Context, text: String): AlertDialog { val code = createQRCode(text) ctx.setTheme(R.style.Theme_TMessages) - android.app.AlertDialog.Builder(ctx).setView(LinearLayout(ctx).apply { + return AlertDialog.Builder(ctx).setView(LinearLayout(ctx).apply { addView(LinearLayout(ctx).apply { @@ -461,28 +462,30 @@ object ProxyUtil { @JvmStatic fun tryReadQR(ctx: Activity, bitmap: Bitmap) { - val intArray = IntArray(bitmap.getWidth() * bitmap.getHeight()) - bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight()) - val source = RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray) + val intArray = IntArray(bitmap.width * bitmap.height) + bitmap.getPixels(intArray, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height) + val source = RGBLuminanceSource(bitmap.width, bitmap.height, intArray) try { - val result = qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source))) - - if (result == null || result.text.isBlank()) { - - AlertUtil.showToast(LocaleController.getString("NoQrFound", R.string.NoQrFound)) - - } else { - - showLinkAlert(ctx, result.text) - + val result = try { + qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source))) + } catch (e: NotFoundException) { + qrReader.decode(BinaryBitmap(GlobalHistogramBinarizer(source.invert()))) } + showLinkAlert(ctx, result.text) + + val intArr = arrayListOf().toIntArray() + } catch (ex: NoSuchMethodError) { AlertUtil.showSimpleAlert(ctx, "很抱歉, 這是一個已知的問題, 但您現在無法掃碼, 因爲您正在使用糟糕的Android系統, 直到 Google Zxing 為您的設備做出優化.") + } catch (e: Throwable) { + + AlertUtil.showToast(LocaleController.getString("NoQrFound", R.string.NoQrFound)) + } } @@ -495,7 +498,7 @@ object ProxyUtil { var isUrl = false runCatching { - text.toHttpUrlOrNull()!! + text.replace("tg://", "https://t.me/").toHttpUrlOrNull()!! if (Browser.isInternalUrl(text, booleanArrayOf(false))) { Browser.openUrl(ctx, text) return diff --git a/TMessagesProj/src/main/res/values/strings_nekox.xml b/TMessagesProj/src/main/res/values/strings_nekox.xml index d6ac985c8..00d8ebc99 100644 --- a/TMessagesProj/src/main/res/values/strings_nekox.xml +++ b/TMessagesProj/src/main/res/values/strings_nekox.xml @@ -252,6 +252,8 @@ Unpin message Unpin all messages Dismiss for yourself - + QR Login + This QR code / link allows someone to log in to your Telegram account. Is this your own operation? + Confirm Login \ No newline at end of file