古いプッシュ購読のURL中の識別子を見て自動移行を行う。アプリデータのインポート時に、使わなくなったカラムのデータを無視する。

This commit is contained in:
tateisu 2023-02-09 06:31:03 +09:00
parent 2d7fceb238
commit 7e7f726e6a
5 changed files with 73 additions and 7 deletions

View File

@ -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";

View File

@ -182,6 +182,7 @@ object AppDataExporter {
cv.clear()
reader.beginObject()
val keys = ArrayList<String>()
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()

View File

@ -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.")
}

View File

@ -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秒たっても未読の時だけプッシュ通知が発生する

View File

@ -357,6 +357,10 @@ class PushRepo(
)
} catch (ex: Throwable) {
subLog.e(ex, "updateSubscription failed.")
daoAccountNotificationStatus.updateSubscriptionError(
account.acct,
ex.withCaption()
)
}
}
prefDevice.timeLastEndpointRegister = System.currentTimeMillis()