From 7e7f726e6a6ed62dfe8a79e040ee5c397493bcae Mon Sep 17 00:00:00 2001 From: tateisu Date: Thu, 9 Feb 2023 06:31:03 +0900 Subject: [PATCH] =?UTF-8?q?=E5=8F=A4=E3=81=84=E3=83=97=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A5=E8=B3=BC=E8=AA=AD=E3=81=AEURL=E4=B8=AD=E3=81=AE?= =?UTF-8?q?=E8=AD=98=E5=88=A5=E5=AD=90=E3=82=92=E8=A6=8B=E3=81=A6=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=A7=BB=E8=A1=8C=E3=82=92=E8=A1=8C=E3=81=86=E3=80=82?= =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=83=87=E3=83=BC=E3=82=BF=E3=81=AE?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=9D=E3=83=BC=E3=83=88=E6=99=82=E3=81=AB?= =?UTF-8?q?=E3=80=81=E4=BD=BF=E3=82=8F=E3=81=AA=E3=81=8F=E3=81=AA=E3=81=A3?= =?UTF-8?q?=E3=81=9F=E3=82=AB=E3=83=A9=E3=83=A0=E3=81=AE=E3=83=87=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=82=92=E7=84=A1=E8=A6=96=E3=81=99=E3=82=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apkGen.pl | 2 ++ .../appsetting/AppDataExporter.kt | 27 +++++++++++++++---- .../juggler/subwaytooter/push/PushMastodon.kt | 26 ++++++++++++++++-- .../juggler/subwaytooter/push/PushMisskey.kt | 21 +++++++++++++++ .../jp/juggler/subwaytooter/push/PushRepo.kt | 4 +++ 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/apkGen.pl b/apkGen.pl index 4abab0d2..2c15f882 100644 --- a/apkGen.pl +++ b/apkGen.pl @@ -15,8 +15,10 @@ sub cmd($){ } } +cmd "./gradlew --stop"; cmd "./gradlew clean"; cmd "./gradlew assembleNoFcmRelease"; cmd "./gradlew assembleFcmRelease"; +cmd "./gradlew --stop"; cmd "mv app/build/outputs/apk/SubwayTooter*.apk app/"; cmd " ls -1t app/SubwayTooter*.apk |head -n 5"; diff --git a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt index 285b877a..a26c6271 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/appsetting/AppDataExporter.kt @@ -182,6 +182,7 @@ object AppDataExporter { cv.clear() reader.beginObject() + val keys = ArrayList() while (reader.hasNext()) { val name = reader.nextName() if (name == null) { @@ -205,6 +206,7 @@ object AppDataExporter { "last_notification_error", "last_subscription_error", "last_push_endpoint", + "sound_uri", -> { reader.skipValue() continue @@ -217,20 +219,35 @@ object AppDataExporter { JsonToken.NULL -> { reader.skipValue() cv.putNull(name) + keys.add(name) } - JsonToken.BOOLEAN -> cv.put(name, if (reader.nextBoolean()) 1 else 0) + JsonToken.BOOLEAN -> { + cv.put(name, if (reader.nextBoolean()) 1 else 0) + keys.add(name) + } - JsonToken.NUMBER -> cv.put(name, reader.nextLong()) + JsonToken.NUMBER -> { + cv.put(name, reader.nextLong()) + keys.add(name) + } - JsonToken.STRING -> cv.put(name, reader.nextString()) + JsonToken.STRING -> { + cv.put(name, reader.nextString()) + keys.add(name) + } - else -> reader.skipValue() + else -> { + reader.skipValue() + log.w("skip $table.$name") + } } } reader.endObject() val new_id = db.replace(table, null, cv) - if (new_id == -1L) error("importTable: invalid row_id") + if (new_id == -1L) { + error("importTable: replace failed. table=$table, names=${keys.joinToString(",")}") + } idMap?.put(old_id, new_id) } reader.endArray() diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt index def8ed12..910cb4e2 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushMastodon.kt @@ -18,6 +18,7 @@ import jp.juggler.util.data.* import jp.juggler.util.log.LogCategory import jp.juggler.util.time.parseTimeIso8601 import kotlinx.coroutines.isActive +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.security.Provider import java.security.SecureRandom import java.security.interfaces.ECPublicKey @@ -88,11 +89,16 @@ class PushMastodon( } } } - if (params["dh"] != deviceHash) { + if (params["dh"] != deviceHash && !isOldSubscription(account, oldEndpointUrl)) { + // この端末で作成した購読ではない。 // TODO: 古い形式のURLを移行できないか? log.w("deviceHash not match. keep it for other devices. ${account.acct} $oldEndpointUrl") subLog.e(R.string.push_subscription_exists_but_not_created_by_this_device) + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + context.getString(R.string.push_subscription_exists_but_not_created_by_this_device) + ) return } } @@ -175,6 +181,22 @@ class PushMastodon( } } + private fun isOldSubscription(account: SavedAccount, url: String): Boolean { + // https://mastodon-msg.juggler.jp + // /webpushcallback + // /{ deviceId(FCM token) } + // /{ acct } + // /{flags } + // /{ client identifier} + + val clientIdentifierOld = url.toHttpUrlOrNull()?.pathSegments?.elementAtOrNull(4) + ?: return false + val installId = prefDevice.installIdV1?.notEmpty() ?: return false + val accessToken = account.bearerAccessToken?.notEmpty() ?: return false + val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url() + return clientIdentifier == clientIdentifierOld + } + private suspend fun isSameAlerts( subLog: SubscriptionLogger, account: SavedAccount, @@ -362,7 +384,7 @@ class PushMastodon( // - notification.user のfull acct がないのでふぁぼ魔ミュートは行えない // - テキスト本文のミュートは…部分的には可能 - if(pm.textExpand?.let{TootStatus.muted_word?.matchShort(it)}==true){ + if (pm.textExpand?.let { TootStatus.muted_word?.matchShort(it) } == true) { error("muted by text word.") } diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt index d7b24b03..8f4db2d0 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushMisskey.kt @@ -18,6 +18,7 @@ import jp.juggler.subwaytooter.pref.prefDevice import jp.juggler.subwaytooter.table.* import jp.juggler.util.data.* import jp.juggler.util.log.LogCategory +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import java.security.Provider import java.security.SecureRandom import java.security.interfaces.ECPublicKey @@ -99,6 +100,10 @@ class PushMisskey( subLog.i(R.string.push_subscription_app_server_hash_missing_but_ok) } else { subLog.e(R.string.push_subscription_app_server_hash_missing_error) + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + context.getString(R.string.push_subscription_app_server_hash_missing_error) + ) } return } else if (willRemoveSubscription) { @@ -160,6 +165,22 @@ class PushMisskey( subLog.i(R.string.push_subscription_completed) } + private fun isOldSubscription(account: SavedAccount, url: String): Boolean { + // https://mastodon-msg.juggler.jp + // /webpushcallback + // /{ deviceId(FCM token) } + // /{ acct } + // /{flags } + // /{ client identifier} + + val clientIdentifierOld = url.toHttpUrlOrNull()?.pathSegments?.elementAtOrNull(4) + ?: return false + val installId = prefDevice.installIdV1?.notEmpty() ?: return false + val accessToken = account.misskeyApiToken?.notEmpty() ?: return false + val clientIdentifier = "$accessToken$installId".digestSHA256Base64Url() + return clientIdentifier == clientIdentifierOld + } + /* https://github.com/syuilo/misskey/blob/master/src/services/create-notification.ts#L46 Misskeyは通知に既読の概念があり、イベント発生後2秒たっても未読の時だけプッシュ通知が発生する。 diff --git a/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt b/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt index b695f3c8..b143470c 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt +++ b/app/src/main/java/jp/juggler/subwaytooter/push/PushRepo.kt @@ -357,6 +357,10 @@ class PushRepo( ) } catch (ex: Throwable) { subLog.e(ex, "updateSubscription failed.") + daoAccountNotificationStatus.updateSubscriptionError( + account.acct, + ex.withCaption() + ) } } prefDevice.timeLastEndpointRegister = System.currentTimeMillis()