Android app (TWA) in android/, built with podman; serve assetlinks.json for it

This commit is contained in:
Astra 2026-10-03 12:44:11 +01:00
parent 44708d5f3c
commit 7900bf5b3e
21 changed files with 313 additions and 0 deletions

View file

@ -4,6 +4,7 @@ import (
"encoding/json"
"io/fs"
"net/http"
"strings"
)
// The site installs as an app (a PWA): a web app manifest, plus the service worker in
@ -62,6 +63,34 @@ func (s *Server) manifest(staff bool) http.HandlerFunc {
}
}
// assetLinks tells Chrome the Android app belongs to this site, so it opens the site full screen
// (a Trusted Web Activity) instead of with its URL bar showing.
func (s *Server) assetLinks(w http.ResponseWriter, r *http.Request) {
var certs []string
for _, c := range s.cfg.AndroidCerts {
if c = strings.ToUpper(strings.TrimSpace(c)); c != "" {
certs = append(certs, c)
}
}
if s.cfg.AndroidPackage == "" || len(certs) == 0 {
http.NotFound(w, r)
return
}
type target struct {
Namespace string `json:"namespace"`
PackageName string `json:"package_name"`
Fingerprints []string `json:"sha256_cert_fingerprints"`
}
type statement struct {
Relation []string `json:"relation"`
Target target `json:"target"`
}
writeJSON(w, http.StatusOK, []statement{{
Relation: []string{"delegate_permission/common.handle_all_urls"},
Target: target{Namespace: "android_app", PackageName: s.cfg.AndroidPackage, Fingerprints: certs},
}})
}
// serviceWorker serves sw.js from the root, since a worker only controls pages under its own path.
func serviceWorker(static fs.FS) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {