feat: age verification
Release / Release (push) Successful in 59s

This commit is contained in:
2026-09-01 22:42:42 +02:00
parent 96a1e1f6b9
commit 74726598be
2 changed files with 37 additions and 1 deletions
@@ -49,6 +49,7 @@ class MorphePatchIntegrationTest {
"--exclusive", "--exclusive",
"--enable=$OUTDATED_PATCH_NAME", "--enable=$OUTDATED_PATCH_NAME",
"--enable=$UPGRADE_PATCH_NAME", "--enable=$UPGRADE_PATCH_NAME",
"--enable=$POST_AGE_VERIFICATION_PATCH_NAME",
"--unsigned", "--unsigned",
"--out=${patchedApk.absolutePathString()}", "--out=${patchedApk.absolutePathString()}",
"--result-file=${resultFile.absolutePathString()}", "--result-file=${resultFile.absolutePathString()}",
@@ -93,7 +94,9 @@ class MorphePatchIntegrationTest {
val appliedPatchNames = result.getAsJsonArray("appliedPatches") val appliedPatchNames = result.getAsJsonArray("appliedPatches")
.map { it.asJsonObject.get("name").asString } .map { it.asJsonObject.get("name").asString }
assertTrue( assertTrue(
appliedPatchNames.containsAll(listOf(OUTDATED_PATCH_NAME, UPGRADE_PATCH_NAME)), appliedPatchNames.containsAll(
listOf(OUTDATED_PATCH_NAME, UPGRADE_PATCH_NAME, POST_AGE_VERIFICATION_PATCH_NAME)
),
"Expected patches were not applied: $appliedPatchNames" "Expected patches were not applied: $appliedPatchNames"
) )
assertTrue(result.getAsJsonArray("failedPatches").isEmpty, "Morphe reported failed patches") assertTrue(result.getAsJsonArray("failedPatches").isEmpty, "Morphe reported failed patches")
@@ -148,6 +151,7 @@ class MorphePatchIntegrationTest {
private companion object { private companion object {
const val OUTDATED_PATCH_NAME = "Disable outdated version screen" const val OUTDATED_PATCH_NAME = "Disable outdated version screen"
const val UPGRADE_PATCH_NAME = "Remove timeline Upgrade button" const val UPGRADE_PATCH_NAME = "Remove timeline Upgrade button"
const val POST_AGE_VERIFICATION_PATCH_NAME = "Remove post age verification"
const val MORPHE_VERSION = "1.13.1" const val MORPHE_VERSION = "1.13.1"
const val MORPHE_SHA256 = "a212531f68d3ada4b504bf9dac3e02460589f3bf8868ee66e1b4780152d3466b" const val MORPHE_SHA256 = "a212531f68d3ada4b504bf9dac3e02460589f3bf8868ee66e1b4780152d3466b"
const val MORPHE_URL = const val MORPHE_URL =
@@ -0,0 +1,32 @@
package app.twitter.patches
import app.morphe.patcher.Fingerprint
import app.morphe.patcher.extensions.InstructionExtensions.addInstructions
import app.morphe.patcher.patch.bytecodePatch
import app.twitter.patches.shared.Constants.COMPATIBILITY_X
private val postAgeVerificationActionFingerprint = Fingerprint(
definingClass = "Lcom/twitter/model/mediavisibility/c${'$'}b;",
name = "a",
returnType = "Lcom/twitter/model/mediavisibility/c;",
parameters = listOf("Ljava/lang/String;")
)
@Suppress("unused")
val removePostAgeVerificationPatch = bytecodePatch(
name = "Remove post age verification",
description = "Allows age-gated posts to be viewed without completing age verification.",
default = true
) {
compatibleWith(COMPATIBILITY_X)
execute {
postAgeVerificationActionFingerprint.method.addInstructions(
0,
"""
const/4 v0, 0x0
return-object v0
"""
)
}
}