update 2026-10-30 07:45:21

This commit is contained in:
action committed 2026-10-30 07:45:21 +08:00
1 parent 76e81abc86
commit 99d6229f91
85 files changed
+16480 -9

No files matched your search

@@ -0,0 +1,2 @@
config footstrap 'settings'
@@ -0,0 +1,42 @@
#!/bin/sh
# Registration plus the symlinks that expose the admin's uploads. Nothing migrates an older footstrap
# (OpenWrt expects a sysupgrade) except the stale pattern symlink removed below.
changed=0
set_opt() {
uci -q get "luci.$1" >/dev/null 2>&1 && return
uci set "luci.$1=$2"
changed=1
}
set_opt themes.Footstrap /luci-static/footstrap
# set_opt never overwrites, and luci-base ships main.mediaurlbase, so on a stock router this line
# sets nothing on install or upgrade: the admin picks Footstrap in Language and Style. An upgrade
# must never move a router off its theme; on an upgrade the themes entry exists, so `changed` is 0
# (apk exports no PKG_UPGRADE).
if [ "${PKG_UPGRADE:-}" != 1 ] && [ "$changed" = 1 ]; then
set_opt main.mediaurlbase /luci-static/footstrap
fi
[ "$changed" = 1 ] && uci commit luci
# uhttpd serves /www only, so uploads live in /etc (kept by lib/upgrade/keep.d) behind symlinks.
# The pattern is NOT symlinked: an SVG opened through a same-origin URL runs as a script with the
# admin's session (OpenWrt forum 251930). cgi-bin/luci-theme-footstrap-pattern serves it under CSP
# 'none' + sandbox + nosniff, which uhttpd cannot attach to a static file.
# The login background stays a symlink: its extension-less name makes uhttpd answer
# application/octet-stream, so a direct open downloads instead of rendering. The canvas re-encode in
# fs-assets.js is compression, not a boundary.
mkdir -p /etc/footstrap
if [ -d /www/luci-static/footstrap ]; then
ln -sf /etc/footstrap/login-bg /www/luci-static/footstrap/bg
ln -sfn /etc/footstrap/fonts /www/luci-static/footstrap/fonts
fi
# Remove a pre-0.14.11 install's stale pattern symlink (a reported security hole); `-L` only, never a
# real file.
[ -L /www/luci-static/footstrap/pattern.svg ] && rm -f /www/luci-static/footstrap/pattern.svg
exit 0
@@ -0,0 +1,7 @@
# Keep the admin's uploads across sysupgrade: login background, pattern, webfonts. They are written
# at runtime, so only a firmware sysupgrade needs them listed. Not conffiles: they live outside
# root/etc/config, and a conffiles entry the package does not ship is rejected.
/etc/footstrap/login-bg
/etc/footstrap/pattern.svg
# Whole directory: the faces without the generated fonts.css leave settings.fonts 404ing every page.
/etc/footstrap/fonts
@@ -0,0 +1,13 @@
{
"admin/system/footstrap": {
"title": "Footstrap",
"order": 3,
"action": {
"type": "view",
"path": "footstrap/appearance"
},
"depends": {
"acl": [ "luci-theme-footstrap" ]
}
}
}
@@ -0,0 +1,37 @@
{
"luci-theme-footstrap": {
"description": "Footstrap theme settings saved to the router, the login background and pattern uploads, and the Footstrap settings page",
"read": {
"uci": [
"footstrap"
]
},
"write": {
"ubus": {
"uci": [
"set",
"commit"
],
"file": [
"remove"
]
},
"uci": [
"footstrap"
],
"cgi-io": [
"upload"
],
"file": {
"/etc/footstrap/login-bg": [
"write",
"remove"
],
"/etc/footstrap/pattern.svg": [
"write",
"remove"
]
}
}
}
}
@@ -0,0 +1,30 @@
#!/bin/sh
# Serves the uploaded wallpaper pattern with headers a browser will not execute: opened directly as
# a /www symlink it was a same-origin document with an authenticated LuCI session in reach (OpenWrt
# forum 251930: a marker SVG read document.cookie, pre-login too). The theme's own use paints it via
# mask-image or background-image, which never run script, so only the direct URL is closed here.
#
# Unauthenticated on purpose: the pattern paints before login (head.ut pre-paint). Safe only because
# the script takes no input: FILE is a constant, never $QUERY_STRING or $PATH_INFO.
FILE=/etc/footstrap/pattern.svg
if [ ! -r "$FILE" ]; then
printf 'Status: 404 Not Found\r\n'
printf 'Content-Type: text/plain\r\n'
printf '\r\n'
exit 0
fi
printf 'Status: 200 OK\r\n'
printf 'Content-Type: image/svg+xml\r\n'
# Cacheable forever: fs-axes.js appends `?v=<token>`, which changes with every upload. A static
# /www file had an ETag; this handler must not make the tile re-fetch on every page load, off flash
# with no gzip.
printf 'Cache-Control: public, max-age=31536000, immutable\r\n'
printf 'X-Content-Type-Options: nosniff\r\n'
printf "Content-Security-Policy: default-src 'none'; sandbox\r\n"
printf '\r\n'
cat "$FILE"
exit 0