SHA256
docs: record verified development delivery and explicit release gates
Document independent native architecture, server compatibility, build/signing procedures, privacy limitations and persistent continuation steps. Record two consecutive seven-test API 35 HTTPS/OIDC passes, portable and host-tool checks, and inspected unsigned artifacts. Explicitly withhold production readiness pending Apple SDK validation, API 37/current-device testing, real IdPs, resource-limit review, human security review and maintainer signing.
This commit is contained in:
1 parent
9ca11e4fb5
commit
2d12491516
13 files changed
+674
No files matched your search
@@ -0,0 +1,41 @@
|
||||
# Architecture
|
||||
|
||||
Two independent native applications share a policy, not a cross-platform runtime:
|
||||
|
||||
| Responsibility | Android | iOS |
|
||||
| --- | --- | --- |
|
||||
| Native entry/configuration | ComponentActivity and platform widgets | SwiftUI |
|
||||
| Web application | Android WebView | WKWebView |
|
||||
| Server URL policy | ServerAddress | ServerAddress |
|
||||
| Reachability/metadata | HttpsURLConnection, no redirects/cookies | Ephemeral URLSession, no redirects/cookies |
|
||||
| Authentication | Upstream web UI and OS cookie jar | Upstream web UI and WKWebsiteDataStore |
|
||||
| OIDC | Separate restricted web view after consent | Separate restricted web view after consent |
|
||||
| Downloads | Origin-bound streaming / bounded blob capture and pull | WKDownload to temporary protected file, system export |
|
||||
|
||||
The client never reimplements a Yuvomi module or introduces a backend. The user
|
||||
selects the origin. Bootstrap calls check the actual upstream unauthenticated
|
||||
metadata contract before loading the server application. Configuration stores only
|
||||
the origin and a query/fragment-free last path; auth/reset/invite routes are not
|
||||
restored. No native password or API-token storage exists.
|
||||
|
||||
The current web view remains alive across background/resume and ordinary rotation.
|
||||
Android handles orientation changes in the existing activity; process recreation
|
||||
loads the remembered path and retains OS cookies, not unsaved web form memory.
|
||||
iOS retains a StateObject-owned view; cold launch restores path and persistent
|
||||
cookies. No resume reload is imposed. Native recovery offers Retry, Keep viewing,
|
||||
and server management without hiding the route back to configuration.
|
||||
|
||||
Server erasure destroys the browsing context and clears all website storage before
|
||||
another server is loaded. The local wipe does not invalidate the remote session;
|
||||
logout is still a server-side operation. Web application history remains native
|
||||
web history. External schemes, universal links and app links are not registered
|
||||
because arbitrary self-hosted domains cannot be verified by this app in advance.
|
||||
|
||||
The optional integration build has a different Android package ID and adds trust
|
||||
for a fresh test CA generated outside the repository. It uses the same production
|
||||
code and the unmodified pinned upstream server. Neither normal debug nor release
|
||||
resources include that CA. Never distribute an integration APK.
|
||||
|
||||
Read-only offline functionality belongs to upstream's service worker. The app
|
||||
preserves it where the platform engine supports it, but does not promise offline
|
||||
editing, synchronization, or the same PWA cache behavior on all OS versions.
|
||||
@@ -0,0 +1,67 @@
|
||||
# Android development
|
||||
|
||||
Requirements: JDK 17, Android SDK platform 37.0, build-tools 36.0.0, current
|
||||
platform-tools, and accepted Android SDK licenses. Minimum Android 8 (API 26).
|
||||
Use a maintained Android System WebView. Target API 37. On Android 17, choose
|
||||
"Allow private-network servers" when using a LAN instance; public HTTPS servers
|
||||
do not need this optional runtime permission. No discovery/scanning is performed.
|
||||
|
||||
```sh
|
||||
export ANDROID_HOME=/path/to/android-sdk
|
||||
bash android/gradlew -p android testDebugUnitTest lintDebug lintRelease assembleDebug assembleRelease bundleRelease
|
||||
bash android/gradlew -p android connectedDebugAndroidTest
|
||||
```
|
||||
|
||||
Gradle 9.6.0 is checksum-verified by the wrapper. AGP 9.4.1 uses built-in Kotlin
|
||||
with the build-cache fix in KGP 2.4.21. Maven versions are locked. No dynamic
|
||||
application dependencies or private Maven repository is required.
|
||||
|
||||
Ordinary outputs:
|
||||
|
||||
- `android/app/build/outputs/apk/debug/app-debug.apk` (development-signed)
|
||||
- `android/app/build/outputs/apk/release/app-release-unsigned.apk`
|
||||
- `android/app/build/outputs/bundle/release/app-release.aab` (unsigned unless signed later)
|
||||
- `android/app/build/reports/` (lint, JVM and emulator results)
|
||||
|
||||
Immediately after building, collect and inspect the outputs:
|
||||
|
||||
```sh
|
||||
python3 scripts/collect-android-artifacts.py
|
||||
```
|
||||
|
||||
This writes ignored `artifacts/android/` copies, `SHA256SUMS`, source identity and
|
||||
manifest/network-policy/signature evidence. It requires `ANDROID_HOME` and respects
|
||||
`YUVOMI_BUILD_DIR`. Source identity records the checkout at collection time; always
|
||||
rebuild immediately beforehand and use a clean worktree for a release candidate.
|
||||
|
||||
The unsigned release cannot be installed/published as-is. See release signing
|
||||
instructions. `gradle-wrapper.jar` is the standard generated Gradle bootstrap
|
||||
binary; it is intentionally versioned, unlike generated APKs or caches.
|
||||
|
||||
On WSL/Windows mounts that reject POSIX metadata operations, put outputs on the
|
||||
Linux filesystem:
|
||||
|
||||
```sh
|
||||
export YUVOMI_BUILD_DIR="$HOME/yuvomi-build"
|
||||
bash android/gradlew -p android testDebugUnitTest assembleDebug
|
||||
```
|
||||
|
||||
The application never permits HTTP, including debug builds. Use real HTTPS for
|
||||
manual development. For a temporary local HTTPS integration environment:
|
||||
|
||||
```sh
|
||||
git clone --filter=blob:none https://github.com/ulsklyc/yuvomi.git /path/to/upstream
|
||||
git -C /path/to/upstream checkout 10bfef7686ed7303b4c74c7fcc55a5eb16356c9d
|
||||
npm ci --omit=dev --prefix /path/to/upstream
|
||||
python3 scripts/test-integration.py /path/to/upstream --android
|
||||
```
|
||||
|
||||
Requires Node 22.14+ and a running emulator. The harness creates and removes its
|
||||
own CA/key/database, uses `adb reverse`, and builds `.integration` with explicit
|
||||
test trust. It does not weaken production TLS. Test credentials are ephemeral.
|
||||
Keep test reports private if you customize the harness with real data (not advised).
|
||||
|
||||
For dependency updates run `:app:dependencies --write-locks`, the full pipeline,
|
||||
and `python3 scripts/check-dependencies.py`. Review lockfile changes. The version
|
||||
update lint recommendations are informational, not suppressed correctness errors;
|
||||
OSV checks independently fail on known advisories.
|
||||
@@ -0,0 +1,39 @@
|
||||
# iOS development
|
||||
|
||||
Requires macOS, Xcode 16.4 or newer with an iOS simulator, and XcodeGen 2.44.1.
|
||||
Minimum iOS/iPadOS 18.4: the auth window must be able to deny native file-panel
|
||||
requests, which earlier WKWebView delegates cannot do. No CocoaPods or external
|
||||
runtime package is required. For App Store submission use Apple's currently
|
||||
required Xcode/iOS SDK, not merely the oldest compiler that can build the source.
|
||||
|
||||
```sh
|
||||
bash scripts/install-xcodegen.sh "$HOME/.local/yuvomi-xcodegen"
|
||||
"$HOME/.local/yuvomi-xcodegen/xcodegen/bin/xcodegen" generate --spec ios/project.yml
|
||||
device=$(python3 scripts/select-simulator.py)
|
||||
xcodebuild -project ios/Yuvomi.xcodeproj -scheme Yuvomi \
|
||||
-destination "platform=iOS Simulator,id=$device" CODE_SIGNING_ALLOWED=NO test
|
||||
xcodebuild -project ios/Yuvomi.xcodeproj -scheme Yuvomi \
|
||||
-destination 'generic/platform=iOS' -archivePath artifacts/Yuvomi-unsigned.xcarchive \
|
||||
CODE_SIGNING_ALLOWED=NO archive
|
||||
```
|
||||
|
||||
`project.yml` is the source of truth. The Xcode project and generated Info.plist
|
||||
are ignored. The XcodeGen download is version- and SHA256-pinned. The project
|
||||
includes a privacy manifest, camera/photo/local-network usage strings, universal
|
||||
app icon, orientation support, unit and UI test targets, and no ATS exception.
|
||||
|
||||
On macOS or Linux with Swift 6 installed:
|
||||
|
||||
```sh
|
||||
swift test --package-path ios
|
||||
swiftc -frontend -parse ios/Sources/*.swift ios/Tests/*.swift ios/UITests/*.swift
|
||||
```
|
||||
|
||||
These portable tests compile the **production URL/metadata policies only**.
|
||||
Parsing does not typecheck UIKit, SwiftUI or WebKit APIs. Neither command is
|
||||
evidence that the iOS application builds. Actual Xcode testing is mandatory.
|
||||
|
||||
For a device build select your authorized development team in Xcode, use your own
|
||||
registered bundle identifier, and let Xcode manage development provisioning.
|
||||
Never commit generated profiles or certificates. See `release-process.md` for
|
||||
distribution. A Linux environment cannot produce a validated iOS archive.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Maintainer continuation
|
||||
|
||||
This is a development delivery, not authorization to publish. Preserve the Git
|
||||
history on `feat/yuvomi-mobile`; use Conventional Commits and normal pushes only.
|
||||
The authorized community remote is `https://git.nesterovic.cc/nessi/Yuvomi-App`.
|
||||
Do not push, submit issues or open pull requests against upstream on this task's
|
||||
behalf. No production credentials or store accounts have been provided.
|
||||
|
||||
## Start with the evidence
|
||||
|
||||
Read [validation](validation.md), [security review](security-review.md), and
|
||||
[release gates](release-process.md). Do not repeat completed implementation work
|
||||
or equate portable Swift checks with an iOS app build. Inspect `git status` before
|
||||
editing; preserve any newer maintainer changes.
|
||||
|
||||
The upstream reference is Yuvomi 2.78.0 at
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. Keep it unmodified. Subpath hosting,
|
||||
browser-to-native OIDC handoff and native remote push are not implemented.
|
||||
|
||||
The extended API 35 HTTPS suite passes all seven tests, including the local-IdP
|
||||
round trip, native transfers, recovery and back navigation. Portable Swift has
|
||||
seven passing policy tests; the separate JUnit verifier has eight regressions.
|
||||
Keep the fixture's scope separate from real-provider or Apple-platform validation.
|
||||
|
||||
## Persistent local environment (Linux/WSL)
|
||||
|
||||
- Repository: `/mnt/c/Users/neste/Documents/GIT/Yuvomi-App`.
|
||||
- Upstream and installed dependencies: `/home/neste/yuvomi-tools/upstream`.
|
||||
- SDK: `/home/neste/yuvomi-tools/android-toolchain/android-sdk`.
|
||||
- Build outputs/logs: `/home/neste/yuvomi-build`.
|
||||
- Swift 6.2.1: `/home/neste/yuvomi-tools/swift-6.2.1-RELEASE-ubuntu24.04/usr/bin`.
|
||||
- Swift compatibility libraries: `/home/neste/yuvomi-tools/compat/usr/lib/x86_64-linux-gnu`.
|
||||
- Swift scratch output: `/home/neste/yuvomi-swift-build`.
|
||||
- ktlint and actionlint: `/home/neste/yuvomi-tools/ktlint.jar` and
|
||||
`/home/neste/yuvomi-tools/actionlint`.
|
||||
- Local collected artifacts/evidence: ignored `artifacts/android/`.
|
||||
|
||||
`/tmp/opencode` is temporary and was cleared by server restarts. Background
|
||||
processes may also disappear. Keep durable logs under `/home/neste`; never persist
|
||||
the integration fixture's generated private CA, keys or real household data.
|
||||
|
||||
```sh
|
||||
export ANDROID_HOME=/home/neste/yuvomi-tools/android-toolchain/android-sdk
|
||||
export YUVOMI_BUILD_DIR=/home/neste/yuvomi-build
|
||||
"$ANDROID_HOME/platform-tools/adb" devices -l
|
||||
"$ANDROID_HOME/platform-tools/adb" shell am get-started-user-state 0
|
||||
# Require RUNNING_UNLOCKED, then:
|
||||
python3 scripts/test-integration.py /home/neste/yuvomi-tools/upstream --android
|
||||
bash android/gradlew -p android testDebugUnitTest lintDebug lintRelease assembleDebug assembleRelease bundleRelease
|
||||
python3 scripts/collect-android-artifacts.py
|
||||
```
|
||||
|
||||
The API 35 AVD is `yuvomi-test`. Its stable attempt uses KVM, `-gpu host`,
|
||||
`-no-window -no-audio -no-boot-anim -no-snapshot -memory 2560 -cores 2`.
|
||||
Launch under the SDK/AVD owner with access to the `kvm` group. Other GPU modes
|
||||
previously crashed the host emulator with SIGSEGV. API 37 had broken services and
|
||||
locked credential-encrypted storage; no API 37 runtime success is claimed.
|
||||
|
||||
For portable Swift checks add the compiler directory to `PATH` and set
|
||||
`LD_LIBRARY_PATH` to the compatibility-library directory above, then use the
|
||||
commands in [iOS development](build-ios.md). Apple application/XCTest/UI/archive
|
||||
validation must happen on macOS with Xcode and real supported devices.
|
||||
|
||||
## Highest-priority external work
|
||||
|
||||
1. Typecheck/build the iOS app against Apple SDKs, run its actual XCTest/UI tests,
|
||||
and produce an unsigned archive. Fix any failures; none of these ran locally.
|
||||
2. Run the API 37 permission grant/denial/revocation scenarios on a working image
|
||||
or device, plus the minimum-supported Android and current WebView matrix.
|
||||
3. Review iOS unknown-length download disk-pressure handling before release.
|
||||
4. Validate real supported IdPs, TOTP after SSO, linking, cancellation, native
|
||||
file/camera pickers, process death, accessibility and offline account isolation.
|
||||
5. Establish private vulnerability reporting, owned identifiers, authorized CI,
|
||||
human security review and owner-controlled signing before any distribution.
|
||||
|
||||
The provided GitHub Actions workflows do not automatically execute on the current
|
||||
non-GitHub forge. Do not claim hosted CI or store readiness without actual runs.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Release process
|
||||
|
||||
No release is authorized by the existence of these scripts. No workflow publishes
|
||||
to either store. A debug APK or unsigned archive is not a production release.
|
||||
|
||||
1. Complete every outstanding gate in `validation.md` and `security-review.md`.
|
||||
Obtain independent human review of authentication, navigation, file handlers,
|
||||
local erasure and privacy disclosures. Run actual supported device/OS tests.
|
||||
2. Resolve bundle/application identifier ownership. `community.yuvomi.mobile` is
|
||||
a provisional community identifier, not proof of registry/store ownership.
|
||||
Confirm use of the Yuvomi name, required attribution and independent status.
|
||||
3. Bump version/name/code in Android and the iOS project spec; update CHANGELOG.
|
||||
4. Run JVM/emulator/real-upstream HTTPS tests, portable Swift and Xcode simulator
|
||||
tests, static checks, OSV scan, release builds and artifact inspection. Record
|
||||
upstream revision, app SHA, OS/WebView/Xcode versions, results and checksums.
|
||||
5. Produce signed artifacts only using an authorized maintainer's credentials.
|
||||
6. Review store privacy/Data Safety answers for the app AND selected-server model,
|
||||
permission rationale, encryption/export compliance, screenshots, support URL,
|
||||
vulnerability contact, and device demonstrations. A functional web companion
|
||||
is not guaranteed to pass Apple's minimum-functionality review.
|
||||
7. Create a release/tag and publish artifacts/store submissions manually only
|
||||
after explicit maintainer authorization. Never force-push or rewrite history.
|
||||
|
||||
## Android
|
||||
|
||||
The manual `release.yml` workflow uses a protected GitHub environment named
|
||||
`release`. Configure branch restrictions and required reviewers before adding
|
||||
secrets. With `sign_android=false` it emits unsigned artifacts. Signing requires:
|
||||
|
||||
- `ANDROID_KEYSTORE_BASE64`
|
||||
- `ANDROID_STORE_PASSWORD`
|
||||
- `ANDROID_KEY_PASSWORD`
|
||||
- `ANDROID_KEY_ALIAS`
|
||||
|
||||
The workflow uses `zipalign`, `apksigner`, and `jarsigner`; private material exists
|
||||
only in a restrictive runner-temporary file removed on exit. Securely back up the
|
||||
real upload key and use Play App Signing according to the owner's policy. No
|
||||
production key is generated here. Manually verify APK/AAB signatures and inspect
|
||||
the final manifest: no debuggable flag, HTTP/test CA or unintended exported component.
|
||||
Never distribute an `.integration` package or include its generated test resources.
|
||||
Run `python3 scripts/collect-android-artifacts.py` immediately after the clean-source
|
||||
build to inspect unsigned outputs and record local hashes/source identity. This
|
||||
collector intentionally rejects signed release outputs; collect before signing.
|
||||
|
||||
## iOS
|
||||
|
||||
The CI archive is unsigned and cannot be uploaded to App Store Connect. An owner
|
||||
needs Apple Developer Program membership, a registered app ID, distribution
|
||||
certificate/private key, provisioning profile and App Store Connect permissions.
|
||||
|
||||
Generate/open the project, choose the authorized team, set the owned bundle ID,
|
||||
select a physical/generic iOS destination, and use Product -> Archive. Validate
|
||||
the archive in Organizer and export using the owner's distribution method. For
|
||||
CLI export use a **locally supplied** ExportOptions.plist with the correct team,
|
||||
method and provisioning mappings:
|
||||
|
||||
```sh
|
||||
xcodebuild -exportArchive -archivePath artifacts/Yuvomi.xcarchive \
|
||||
-exportPath artifacts/ios -exportOptionsPlist /secure/path/ExportOptions.plist
|
||||
```
|
||||
|
||||
Do not add distribution certificates, profiles, App Store keys or passwords to the
|
||||
repository. Device camera, Files, VoiceOver, memory pressure and app-switcher
|
||||
privacy need physical-device validation beyond simulator tests.
|
||||
|
||||
## CI hosting
|
||||
|
||||
GitHub Actions files are provided, but the configured community remote is hosted
|
||||
on a different forge. GitHub workflows will not automatically run there. Enable
|
||||
an authorized GitHub mirror/repository (or port the jobs to the forge's runner)
|
||||
and inspect real runs before claiming CI is operational. No destination is
|
||||
created automatically. CI service availability is not an application dependency.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Security review record
|
||||
|
||||
This is an engineering review, not an independent penetration test or certification.
|
||||
|
||||
Addressed during implementation:
|
||||
|
||||
- Canonical, HTTPS-only origin/port comparison; credential, fragment, query,
|
||||
subpath, scheme, lookalike-host and TLS-downgrade regression cases.
|
||||
- A main-frame POST can bypass Android's usual navigation callback. The request
|
||||
interception gate now rejects **all** cross-origin requests, not only subresources.
|
||||
The emulator regression was observed failing when the main-frame guard was
|
||||
deliberately removed, then rerun with the fix restored.
|
||||
- TLS failures cancel by default. Native download redirects are refused before
|
||||
cookies can be replayed to another origin. Bootstrap requests use neither
|
||||
cookies nor automatic redirects and have bounded metadata reads/timeouts.
|
||||
- Files use explicit system selection/content URIs; no filesystem or storage
|
||||
permission is granted to web content. Blob exports have no native JS bridge.
|
||||
- Complete Android browsing-data deletion uses WebStorageCompat, with OS app
|
||||
reset for engines without that capability. WebStorage.deleteAllData alone was
|
||||
insufficient for service-worker CacheStorage/IndexedDB and is not relied upon.
|
||||
- iOS server erase replaces the WKWebView, not only its URL, eliminating old
|
||||
history/back-forward contexts as well as persistent website data.
|
||||
- iOS metadata uses typed decoding, rejecting numeric values masquerading as booleans.
|
||||
- Native picker results are bound to the browsing generation/request. Android
|
||||
rejects stale upload/download selections, revokes camera URI grants, and clears
|
||||
capture cache on erasure. iOS ignores export-cancellation callbacks from an old
|
||||
download. Apple-specific callback regressions have not run without Xcode.
|
||||
- KGP was upgraded after OSV identified CVE-2026-53914 in the original build tool.
|
||||
The final OSV scan found no listed advisories across 213 locked/direct Maven
|
||||
coordinates and build plugins. Rescan after resolution/lock updates.
|
||||
- The inspected release APK is not debuggable, rejects cleartext, disables backup
|
||||
and trusts system CAs only. AndroidX's exported profile installer receiver is
|
||||
protected by the system DUMP permission; app providers are not exported.
|
||||
|
||||
Release gates still requiring evidence:
|
||||
|
||||
- Actual Xcode typecheck, simulator, archive, physical-device and accessibility review.
|
||||
- End-to-end IdP flows, especially providers that prohibit embedded agents; no
|
||||
browser-to-native session transfer is supported by the current upstream protocol.
|
||||
- iOS unknown-length download disk-pressure behavior; a post-download size check
|
||||
is not a streaming quota. Verify file picker/camera cancellation on real devices.
|
||||
- Android file-picker/camera/rotation while a picker is outstanding; cancellation
|
||||
on process death intentionally loses the selection, never silently retries it.
|
||||
- Offline sign-out/account switching, stale-worker updates and server erasure on
|
||||
current WebView/WKWebView versions. Upstream tests are not native device proof.
|
||||
- Reverify final signed release manifests, signing, store ownership, private vulnerability contact
|
||||
and applicable privacy disclosures. No claim that all vulnerabilities are absent.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Server compatibility and authentication
|
||||
|
||||
Source reference: upstream 2.78.0 revision
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. No general version range has been
|
||||
certified. Anonymous bootstrap metadata deliberately omits the exact version;
|
||||
native probing verifies shape, not an invented minimum-version comparison.
|
||||
|
||||
Use `https://family.example.com` or `https://family.example.com:8443`, backed by a
|
||||
root-hosted Yuvomi installation and a valid system-trusted certificate. Operators
|
||||
should set `SESSION_SECURE=true`, correct `BASE_URL`, and correct proxy trust.
|
||||
Private servers are supported through reachable HTTPS/VPN, not TLS bypasses.
|
||||
International hostnames should be entered in ASCII/punycode for both platforms.
|
||||
|
||||
Root-relative assets, API endpoints, cookie paths, callback redirects and worker
|
||||
registration mean `/yuvomi/` subpaths are not supported by the inspected source.
|
||||
Use a dedicated hostname. Reverse proxies must pass `/api/v1/*`, cookies, HTML,
|
||||
JavaScript and the service worker consistently. An external authentication proxy
|
||||
that intercepts bootstrap calls is rejected with a connection error; it is not
|
||||
silently identified as a Yuvomi server.
|
||||
|
||||
## Authentication
|
||||
|
||||
Password login, TOTP/recovery codes, password reset, invitations, server-side
|
||||
session expiry/revocation and logout remain upstream web flows. No native code
|
||||
stores the password, supplies a CSRF bypass, or extends an expired session.
|
||||
Backgrounding does not clear cookies. Native server erasure does not revoke a
|
||||
remote session; use Yuvomi logout first or revoke sessions server-side.
|
||||
|
||||
### OIDC: local fixture verified; real-provider validation pending
|
||||
|
||||
The initiating Yuvomi session contains OIDC state, nonce and PKCE verifier. When
|
||||
the server redirects to an identity provider, native consent offers an isolated
|
||||
web sign-in window sharing the OS website cookie store. HTTPS-only redirects
|
||||
can return to the server callback; the final same-origin page returns to the main
|
||||
view. No app-capability handlers or JS bridge are installed in that auth window.
|
||||
|
||||
Some providers (including configurations that prohibit embedded user agents)
|
||||
require a system browser. **Those cannot sign the native view in with upstream's
|
||||
current protocol.** Use Server settings -> Open server in browser, and sign in
|
||||
there for an independent browser session. Opening only the external authorization
|
||||
link in a browser does not transfer the initiating cookie. Browser cookies are
|
||||
never copied into the app, and custom-scheme callbacks are not fabricated.
|
||||
|
||||
The API 35 integration suite completes a native isolated-window round trip with
|
||||
a local test IdP, real RS256 ID tokens, nonce and S256 PKCE. No external
|
||||
IdP/developer account was supplied. Validate the actual provider, including
|
||||
cross-site cookies, cancellation, errors, TOTP and account linking, before relying
|
||||
on that deployment. iOS authentication has not run against Apple SDKs. A native
|
||||
browser handoff would require an independently reviewed upstream protocol; no
|
||||
such upstream change is included or published.
|
||||
|
||||
Android generated exports require a current WebView supporting document-start
|
||||
scripts and are capped at 25 MB. A bounded Blob registry preserves a generated
|
||||
file even when upstream immediately revokes its object URL; it does not fetch
|
||||
blob URLs or alter the server's CSP. HTTPS file downloads are capped at 100 MB.
|
||||
Update the system WebView if generated exports are unavailable on an old engine.
|
||||
|
||||
## Notifications and offline
|
||||
|
||||
Upstream implements Web Push and optional ntfy/Gotify/webhook/email channels.
|
||||
Embedded web views do not supply a portable native push subscription. This app
|
||||
has **no native remote-push claim**, no Firebase/APNs secrets, no background
|
||||
polling service, and no fake notification-registration UI. Configure an existing
|
||||
optional upstream ntfy/Gotify channel and its client if desired. No centralized
|
||||
service is required by this application.
|
||||
|
||||
Upstream service-worker caching is read-only, allow-listed, and versioned.
|
||||
Mutations/authentication remain online. Platform-specific cache/resume behavior
|
||||
and offline account switching still need device validation. Do not rely on offline
|
||||
editing, synchronization, or closed-app push in this native development build.
|
||||
@@ -0,0 +1,130 @@
|
||||
# Validation status
|
||||
|
||||
**Partially verified development software, not production-ready.**
|
||||
Local validation date: 2026-10-21. No unexecuted iOS application test, hosted CI
|
||||
run, production signing, or store publication is represented as completed.
|
||||
|
||||
## Executed evidence
|
||||
|
||||
- Android debug APK and unsigned release APK/AAB built successfully; both
|
||||
`lintDebug` and `lintRelease` passed. JVM security/picker-policy tests: **7 passed,
|
||||
zero failures/skips**.
|
||||
- Android API 35 regular emulator suite: **6 passed, zero failures/skips**.
|
||||
This covers onboarding, invalid URLs, background/resume, hardened settings,
|
||||
cross-origin POST/subresource isolation, opaque-page Blob rejection and activity
|
||||
recreation. Its permission test checks that the API 37 permission UI is absent;
|
||||
it is **not** evidence of API 37 permission grant/denial behavior.
|
||||
- Unmodified pinned upstream ran behind a temporary HTTPS reverse proxy.
|
||||
Bootstrap metadata, password login, Secure/HttpOnly/SameSite cookies, persistent
|
||||
session, CSRF rejection, logout/revocation passed in the harness.
|
||||
- Android's extended real-server scenario exercises login, HttpOnly cookies,
|
||||
document upload via upstream fetch, native FileTransfer output, bounded Blob
|
||||
export, background/resume, recreation, CSRF-protected logout, revocation,
|
||||
recovery, isolated OIDC return and back navigation. It does not automate the OS
|
||||
camera/document destination picker or prove every upstream module works.
|
||||
Two consecutive API 35 runs have **7 passed, zero failures/skips each**, including the
|
||||
six regular security/onboarding cases and this real-server scenario.
|
||||
- The cross-origin POST regression was deliberately observed failing without its
|
||||
guard. The production guard was restored and the API 35 regression passes.
|
||||
- Portable Swift production-policy tests: 7 passed (URL and typed metadata).
|
||||
All Swift sources passed format lint and parsing with Swift 6.2.1 on Linux.
|
||||
The portable package excludes BrowserModelTests. This does not build iOS.
|
||||
- Selected upstream suites ran successfully: cookie-secure-flag (4),
|
||||
session-sliding (8), two-factor (22), password-reset (24), sw-api-cache (42).
|
||||
Upstream's plain OIDC script also exited successfully. These are upstream tests,
|
||||
not evidence of a provider round-trip or native push support.
|
||||
- The HTTPS harness independently passed upstream OIDC discovery, RS256 ID-token
|
||||
signature/nonce validation, S256 PKCE exchange and session creation with a local
|
||||
test IdP. The fixture checks single-use codes, exact redirect URIs and OAuth
|
||||
Basic client authentication. Loopback hosts/ports and automatic fixture consent
|
||||
are not representative of every provider's cross-site/embedded-agent policies.
|
||||
- OSV: no listed advisories for **213** locked/direct Maven coordinates and build
|
||||
plugins at scan time. This is not a guarantee that no vulnerabilities exist.
|
||||
- ktlint 1.7.1, actionlint 1.7.7, repository invariants, Python compilation,
|
||||
Node syntax and shell syntax checks passed. JUnit-verifier regression suite:
|
||||
**8 passed**, including rejection of absent, empty, malformed, insufficient,
|
||||
failed, errored and skipped evidence.
|
||||
- Release APK inspection confirms API 26 minimum / API 37 target, no debuggable
|
||||
flag, backups and cleartext disabled, system-only certificate trust. Exported
|
||||
entry points are the launcher and AndroidX ProfileInstallReceiver protected by
|
||||
the system DUMP permission; file/startup providers are not exported. Debug APK
|
||||
signature verifies; release APK/AAB are unsigned. Collected archives contain no
|
||||
fixture CA/key or signing-key files.
|
||||
|
||||
## Emulator limitations and retry evidence
|
||||
|
||||
Earlier extended-suite attempts crashed the host emulator with SIGSEGV under
|
||||
software/off GPU modes. Host-GPU mode remained running and produced actionable
|
||||
JUnit failures: an OIDC-return synchronization timeout, followed by an outage
|
||||
assertion that incorrectly assumed the upstream worker could not serve its cached
|
||||
app shell, then a document-readiness race after recreation. Tests now verify the
|
||||
loaded JavaScript origin, wait for the sign-in window to close, retry only a probe
|
||||
lost to document replacement and exercise recovery through uncached metadata.
|
||||
The completed retry passes all seven tests without disabling the worker or
|
||||
weakening production TLS/CSP/origin policies.
|
||||
|
||||
API 37 attempts encountered broken package/activity services and locked
|
||||
credential-encrypted storage. **No API 37 runtime pass is claimed.**
|
||||
|
||||
Local logs and reports live in `/home/neste/yuvomi-build/`; test XML is under
|
||||
`app/outputs/androidTest-results/connected/`. Earlier failing JUnit snapshots are
|
||||
preserved as `integration-host-gpu-oidc-race.xml` and
|
||||
`integration-host-gpu-sw-cache.xml`, plus
|
||||
`integration-host-gpu-document-ready.xml`. Passing evidence is preserved in
|
||||
`integration-api35-first-pass.xml` and `integration-api35-repeat-pass.xml`; logs are
|
||||
`upstream-integration-final-retry.log` and `upstream-integration-repeat.log`.
|
||||
These files are local evidence, not published
|
||||
artifacts or a hosted CI result.
|
||||
|
||||
Test environment: JDK 17.0.20.1, Node 22.22.1, Python 3.14.4, Android Emulator
|
||||
37.2.12, API 35 x86_64 Google APIs image, WebView 124.0.6367.219. The old bundled
|
||||
WebView is useful compatibility evidence, not a recommendation to use an unpatched
|
||||
engine; a current engine/device run remains mandatory.
|
||||
|
||||
## Artifacts
|
||||
|
||||
Ignored `artifacts/android/` contains the development-signed debug APK and unsigned
|
||||
release APK/AAB, `SHA256SUMS`, `build-info.json` and manifest/policy/signature
|
||||
inspection evidence. No integration APK is collected. No IPA or Apple archive
|
||||
exists. See [Android build](build-android.md) for repeatable collection commands.
|
||||
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
bash android/gradlew -p android testDebugUnitTest lintDebug lintRelease assembleDebug assembleRelease bundleRelease connectedDebugAndroidTest
|
||||
python3 scripts/test-integration.py /path/to/pinned-upstream --android
|
||||
swift test --package-path ios
|
||||
swiftc -frontend -parse ios/Sources/*.swift ios/Tests/*.swift ios/UITests/*.swift
|
||||
python3 scripts/check-repository.py
|
||||
python3 scripts/check-dependencies.py
|
||||
python3 scripts/test-verifier.py
|
||||
python3 scripts/collect-android-artifacts.py
|
||||
git diff --check
|
||||
```
|
||||
|
||||
This environment is Linux/WSL. Android SDK and a KVM emulator were installed for
|
||||
real execution. Build output relocation was needed because the Windows mount
|
||||
rejects some Gradle POSIX metadata operations. Swift's Linux toolchain was
|
||||
installed for portable tests. No macOS, Xcode, Apple simulator or physical device
|
||||
is available; no iOS build/archive/UI result is claimed.
|
||||
|
||||
## Mandatory remaining evidence
|
||||
|
||||
- Run Xcode build, XCTest/UI tests and unsigned archive on macOS; fix any compiler
|
||||
or runtime issues. The app has **not** yet been typechecked against Apple SDKs.
|
||||
- Validate real IdPs: cancellation, account linking, TOTP after OIDC, and embedded
|
||||
provider policy. Browser-only providers have no native-session handoff upstream.
|
||||
- Real-device camera/document picker cancellation, file MIME cases, rotation with
|
||||
an outstanding picker, network loss/reconnect, process kill/memory pressure,
|
||||
session expiry/revocation, OS backup, and offline account isolation.
|
||||
- Android 17 private-network permission grant/denial/revocation on a matching OS.
|
||||
Also run minimum-supported API 26 and a current OS/WebView device matrix.
|
||||
- VoiceOver/TalkBack, large text, contrast, keyboard/safe areas, reduced motion,
|
||||
light/dark appearance and responsive web modules on actual supported devices.
|
||||
- Operational CI runs on an authorized GitHub repository/runner, private security
|
||||
reporting contact, human security review, store ownership and production signing.
|
||||
|
||||
No Firebase/APNs registration, closed-app push, offline editing, App Store approval,
|
||||
signing, publication or physical-device validation is claimed. See `SECURITY.md`
|
||||
and `docs/security-review.md` for residual limitations.
|
||||
Resume work using [maintainer continuation](continuation.md).
|
||||
Reference in new issue
Block a user