diff --git a/scripts/checks/no-gallery-data.sh b/scripts/checks/no-gallery-data.sh new file mode 100755 index 0000000..5593465 --- /dev/null +++ b/scripts/checks/no-gallery-data.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# JR-041 — the plugin never fetches, stores, or transmits gallery data. +# +# Like JR-021 this is a requirement to *not do* something, so it is verified by +# absence. It mirrors the server's UR-012, which is preserved the same way: there +# is no field capable of carrying an embedding or a crop, and no code that would +# read one. +# +# The plugin's whole contact with identity is public identifiers (JR-007) and +# scene windows (JR-004). A reference face or a 512-d vector arriving here would +# mean SR-005 had been breached upstream, so the check is for any *parse* of one +# — a field name, a property, a type — not merely for network calls. +# +# TRACES: JR-041 | SR-005 +set -euo pipefail + +cd "$(dirname "$0")/../.." +roots=("Jellyfin.Plugin.JRay") +status=0 + +# Field and property names that would carry gallery data. Matched as whole words +# so that unrelated identifiers containing them are not false positives. +banned='\b(embedding|embeddings|face_crop|faceCrop|FaceCrop|reference_face|referenceFace|ReferenceFace|mugshot|Mugshot|gallery_vector|galleryVector|descriptor512|Embedding)\b' + +if grep -rn --include='*.cs' --include='*.js' -E "$banned" "${roots[@]}"; then + echo "FAIL (JR-041): a gallery-data field or type is referenced in the plugin." >&2 + status=1 +fi + +# A base64 blob is the other shape this could arrive in. The plugin has no +# legitimate reason to decode one: every string it handles is a name, an id, or +# a URL. +if grep -rn --include='*.cs' -E '\bConvert\.FromBase64String\b' "${roots[@]}"; then + echo "FAIL (JR-041): base64 decoding found — the plugin handles no binary payloads." >&2 + status=1 +fi + +if [ "$status" -eq 0 ]; then + echo "OK (JR-041): no gallery-data code path." +fi + +exit "$status"