Android: old host name out of the pinned-root config and the S-1 fixture
- Pinned-root network security config (D-082) is now a template in app/src/releasePinnedRoot/; with kvitt.tls.pinnedRoot=true the task generatePinnedRootNetworkSecurityConfig writes it into the release resources with the domain kvitt.publicHost (D-121), and stops with a clear message while the root src/release/res/raw/kvitt_root_ca.crt is not committed (fallback unprepared, SPEC 10.5.3). Comment: pinned NPM root (D-120). - Port 443 (D-124): RELEASE_SERVER_URL is https://<kvitt.publicHost> without a port (RELEASE_SERVER_PORT removed); the AC-2.6 intent filter has no android:port; InviteLink drops an explicit default port. - S-1 fixture GOLDEN_SERVER https://kvitt.example.org; 28 S-1 goldens re-recorded (only the server row changed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
@@ -18,7 +18,7 @@ val localProperties = Properties().apply {
|
||||
val releaseStoreFile: String? = localProperties.getProperty("kvitt.release.storeFile")
|
||||
|
||||
// D-121: Kvitt's public host name (SPEC §8.5, §10.6), as BuildConfig.PUBLIC_HOST, the manifest placeholder publicHost
|
||||
// (the https invite links of AC-2.6, port 8443) and RELEASE_SERVER_URL = https://<host>:8443 (AC-2.7). From
|
||||
// (the https invite links of AC-2.6, default port 443, D-124) and RELEASE_SERVER_URL = https://<host> (AC-2.7). From
|
||||
// -Pkvitt.publicHost (infra/publish-apk.sh passes it, from KVITT_PUBLIC_HOST in infra/pi/.env), else the key
|
||||
// kvitt.publicHost in android/local.properties (the owner sets it there; never committed), else the placeholder
|
||||
// kvitt.example.invalid (RFC 2606: never resolves), so a release built without it cannot talk to a real host. Debug
|
||||
@@ -32,9 +32,31 @@ require(Regex("[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+"
|
||||
"kvitt.publicHost must be a host name such as kvitt.duckdns.org (no scheme, port or path), was '$publicHost'"
|
||||
}
|
||||
|
||||
// SPEC §10.5.3: the pinned Caddy root replaces the system anchors for icehack.asuscomm.com only when this is true.
|
||||
// SPEC §10.5.3 (D-082): the pinned NPM root (D-120) replaces the system anchors for kvitt.publicHost only when this is true.
|
||||
val pinnedRoot = providers.gradleProperty("kvitt.tls.pinnedRoot").orElse("false").get().toBoolean()
|
||||
|
||||
/**
|
||||
* Writes res/xml/network_security_config.xml from [template] with `@PUBLIC_HOST@` replaced by [host] (D-121). The
|
||||
* fallback is not prepared (§10.5.3): without the committed root [rootCa] the build stops here with that message.
|
||||
*/
|
||||
abstract class PinnedRootConfigTask : DefaultTask() {
|
||||
@get:InputFile @get:PathSensitive(PathSensitivity.NONE) abstract val template: RegularFileProperty
|
||||
@get:Input abstract val host: Property<String>
|
||||
@get:Internal abstract val rootCa: RegularFileProperty
|
||||
@get:OutputDirectory abstract val outputDir: DirectoryProperty
|
||||
|
||||
@TaskAction
|
||||
fun write() {
|
||||
val ca = rootCa.get().asFile
|
||||
if (!ca.isFile) throw GradleException("kvitt.tls.pinnedRoot=true needs the pinned root ${ca.path} (SPEC §10.5.3)")
|
||||
val root = outputDir.get().asFile
|
||||
root.deleteRecursively()
|
||||
val xml = root.resolve("xml/network_security_config.xml")
|
||||
xml.parentFile.mkdirs()
|
||||
xml.writeText(template.get().asFile.readText().replace("@PUBLIC_HOST@", host.get()))
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "se.hagstedt.kvitt"
|
||||
defaultConfig {
|
||||
@@ -77,10 +99,20 @@ android {
|
||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
// The pinned-root network security config (and the committed kvitt_root_ca.crt in src/release/res/raw) only
|
||||
// when kvitt.tls.pinnedRoot=true; otherwise src/main's system-anchors config applies.
|
||||
if (pinnedRoot) getByName("release").res.directories.add("src/releasePinnedRoot/res")
|
||||
}
|
||||
|
||||
// The pinned-root network security config (generated from src/releasePinnedRoot, trusting src/release/res/raw/
|
||||
// kvitt_root_ca.crt) only in release builds and only when kvitt.tls.pinnedRoot=true; otherwise src/main's
|
||||
// system-anchors config applies.
|
||||
if (pinnedRoot) {
|
||||
val pinnedRootConfig = tasks.register("generatePinnedRootNetworkSecurityConfig", PinnedRootConfigTask::class.java) {
|
||||
description = "Writes the pinned-root network security config for kvitt.publicHost (SPEC §10.5.3)."
|
||||
template.set(layout.projectDirectory.file("src/releasePinnedRoot/network_security_config.xml"))
|
||||
host.set(publicHost)
|
||||
rootCa.set(layout.projectDirectory.file("src/release/res/raw/kvitt_root_ca.crt"))
|
||||
}
|
||||
androidComponents.onVariants(androidComponents.selector().withBuildType("release")) { variant ->
|
||||
variant.sources.res?.addGeneratedSourceDirectory(pinnedRootConfig, PinnedRootConfigTask::outputDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user