feat(macos): Verae Timestamping in Print Destination list

Replace buried PDF Services as the primary UX with an IPP Everywhere
virtual printer (ippeveprinter LaunchAgent) named Verae Timestamping.
Jobs save {name}.pdf + {name}-verae-timestamp-{RECEIPTID}.pdf.
Also add /Applications/Verae Print Stamp.app for drop/Open With.
This commit is contained in:
George Lambert 2026-10-03 04:10:17 -04:00
commit b40e862082
7 changed files with 370 additions and 3 deletions

View file

@ -9,9 +9,11 @@ Only the SHA-256 digest is sent to Verae. Document bytes never leave the machine
```bash ```bash
cd /Users/marchon/research/PrintToVeraeTimeStamp cd /Users/marchon/research/PrintToVeraeTimeStamp
go build -o "$HOME/bin/verae-print" ./cmd/verae-print go build -o "$HOME/bin/verae-print" ./cmd/verae-print
verae-print install-macos verae-print install-printer # Print → Destination → Verae Timestamping
``` ```
Optional (buried PDF submenu): `verae-print install-macos`
Ensure `$HOME/bin` is on your `PATH`. Refresh Verae Time login when the JWT expires: Ensure `$HOME/bin` is on your `PATH`. Refresh Verae Time login when the JWT expires:
```bash ```bash
@ -31,7 +33,9 @@ chmod 600 ~/.verae/xverae-token
## Usage ## Usage
In any app: **File → Print → PDF → Timestamp with Verae** (or **Timestamp with Verae (Zapier)**). In any app: **File → Print → Destination → Verae Timestamping → Print**.
Also: drop a PDF on **Verae Print Stamp** in `/Applications`, or **Open With**.
CLI: CLI:

View file

@ -23,6 +23,8 @@ func main() {
os.Exit(runStamp(os.Args[2:])) os.Exit(runStamp(os.Args[2:]))
case "install-macos": case "install-macos":
os.Exit(runInstallMacOS(os.Args[2:])) os.Exit(runInstallMacOS(os.Args[2:]))
case "install-printer":
os.Exit(runInstallPrinter())
case "version", "-version", "--version": case "version", "-version", "--version":
fmt.Println(job.HelperVersion) fmt.Println(job.HelperVersion)
case "help", "-h", "--help": case "help", "-h", "--help":
@ -43,7 +45,8 @@ func usage() {
Usage: Usage:
verae-print stamp [--channel=verae|zapier] [--out-dir DIR] [--name STEM] [--open] <file.pdf> verae-print stamp [--channel=verae|zapier] [--out-dir DIR] [--name STEM] [--open] <file.pdf>
verae-print install-macos # install PDF Services menu items verae-print install-printer # Destination list: Verae Timestamping (recommended)
verae-print install-macos # also install PDF Services menu items (legacy)
verae-print version verae-print version
Channels: Channels:
@ -117,6 +120,42 @@ func runStamp(args []string) int {
return 0 return 0
} }
func runInstallPrinter() int {
script := filepath.Join(repoRootHint(), "platform", "macos", "ipp", "install-ipp-printer.sh")
if _, err := os.Stat(script); err != nil {
// fall back next to executable
exe, _ := os.Executable()
exe, _ = filepath.EvalSymlinks(exe)
script = filepath.Join(filepath.Dir(exe), "..", "platform", "macos", "ipp", "install-ipp-printer.sh")
}
if abs, err := filepath.Abs(script); err == nil {
script = abs
}
cmd := exec.Command("/bin/bash", script)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = os.Environ()
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "install-printer failed: %v\n(run platform/macos/ipp/install-ipp-printer.sh)\n", err)
return 1
}
return 0
}
func repoRootHint() string {
// Prefer known research path; else cwd
candidates := []string{
"/Users/marchon/research/PrintToVeraeTimeStamp",
".",
}
for _, c := range candidates {
if st, err := os.Stat(filepath.Join(c, "platform", "macos", "ipp", "install-ipp-printer.sh")); err == nil && !st.IsDir() {
return c
}
}
return "."
}
func runInstallMacOS(args []string) int { func runInstallMacOS(args []string) int {
fs := flag.NewFlagSet("install-macos", flag.ExitOnError) fs := flag.NewFlagSet("install-macos", flag.ExitOnError)
bin := fs.String("bin", "", "path to verae-print binary (default: this executable)") bin := fs.String("bin", "", "path to verae-print binary (default: this executable)")

View file

@ -0,0 +1,116 @@
#!/bin/bash
# CUPS backend: verae — virtual printer "Verae Timestamping"
# Discovery (no args): advertise device URI verae:/
# Job: spool PDF and run verae-print as the job user (digests only).
set -euo pipefail
LOG_ROOT="/var/log/cups"
BACKEND_LOG="${LOG_ROOT}/verae-backend.log"
log() {
echo "$(date -u +%Y-%m-%dT%H:%MZ) $*" >>"$BACKEND_LOG" 2>/dev/null || true
}
# Device discovery
if [[ $# -eq 0 ]]; then
echo 'direct verae:/ "Verae Timestamping" "Verae Timestamping — digests-only stamp"'
exit 0
fi
JOB_ID="${1:-}"
JOB_USER="${2:-}"
JOB_TITLE="${3:-document}"
# copies=$4 options=$5
JOB_FILE="${6:-}"
VERAE_PRINT="${VERAE_PRINT_BIN:-/Users/marchon/bin/verae-print}"
CHANNEL="${VERAE_PRINT_CHANNEL:-verae}"
SPOOL_BASE="/Users/Shared/VeraePrintSpool"
# Prefer per-user Application Support when home is known
if [[ -n "$JOB_USER" && -d "/Users/$JOB_USER" ]]; then
SPOOL_BASE="/Users/$JOB_USER/Library/Application Support/Verae/print-spool"
fi
mkdir -p "$SPOOL_BASE"
chmod 700 "$SPOOL_BASE" 2>/dev/null || true
SAFE_TITLE=$(echo "$JOB_TITLE" | tr -cd 'A-Za-z0-9._ -' | head -c 80)
SAFE_TITLE=${SAFE_TITLE:-document}
WORK="$SPOOL_BASE/job-${JOB_ID}-$$"
mkdir -p "$WORK"
INPUT="$WORK/input.dat"
if [[ -n "$JOB_FILE" && -f "$JOB_FILE" ]]; then
cp "$JOB_FILE" "$INPUT"
else
cat >"$INPUT"
fi
# Normalize to PDF when CUPS gave PostScript / other
PDF="$WORK/${SAFE_TITLE}.pdf"
CONTENT_TYPE="${CONTENT_TYPE:-application/pdf}"
case "$CONTENT_TYPE" in
application/pdf|application/x-pdf)
cp "$INPUT" "$PDF"
;;
application/postscript|application/vnd.cups-postscript)
if command -v /usr/bin/pstopdf >/dev/null 2>&1; then
/usr/bin/pstopdf "$INPUT" -o "$PDF" 2>/dev/null || cp "$INPUT" "$PDF"
else
# macOS often still delivers PDF despite PS content-type
if [[ "$(head -c 4 "$INPUT")" == "%PDF" ]]; then
cp "$INPUT" "$PDF"
else
log "job $JOB_ID: cannot convert $CONTENT_TYPE; saving raw"
cp "$INPUT" "$PDF"
fi
fi
;;
*)
if [[ "$(head -c 4 "$INPUT")" == "%PDF" ]]; then
cp "$INPUT" "$PDF"
else
log "job $JOB_ID: content-type=$CONTENT_TYPE; assuming PDF bytes"
cp "$INPUT" "$PDF"
fi
;;
esac
log "job=$JOB_ID user=$JOB_USER title=$JOB_TITLE pdf=$PDF channel=$CHANNEL"
OUT_DIR="/Users/${JOB_USER}/Documents/Verae Timestamps"
if [[ -z "$JOB_USER" || ! -d "/Users/$JOB_USER" ]]; then
OUT_DIR="$SPOOL_BASE/out"
fi
mkdir -p "$OUT_DIR"
run_stamp() {
if [[ -x "$VERAE_PRINT" ]]; then
"$VERAE_PRINT" stamp -channel "$CHANNEL" -out-dir "$OUT_DIR" -name "$SAFE_TITLE" -open "$PDF"
else
log "verae-print missing at $VERAE_PRINT"
return 1
fi
}
# Drop privileges to job user when we are root
if [[ "$(id -u)" -eq 0 && -n "$JOB_USER" && "$JOB_USER" != "root" ]]; then
chown -R "$JOB_USER" "$WORK" "$OUT_DIR" 2>/dev/null || true
if command -v sudo >/dev/null 2>&1; then
sudo -u "$JOB_USER" -H "$VERAE_PRINT" stamp -channel "$CHANNEL" -out-dir "$OUT_DIR" -name "$SAFE_TITLE" -open "$PDF" \
>>"$BACKEND_LOG" 2>&1 || {
log "stamp failed for job $JOB_ID"
# Still exit 0 so the print dialog doesn't hang; user can check log
exit 0
}
else
run_stamp >>"$BACKEND_LOG" 2>&1 || true
fi
else
run_stamp >>"$BACKEND_LOG" 2>&1 || true
fi
# Cleanup work dir; keep outputs in OUT_DIR
rm -rf "$WORK" 2>/dev/null || true
exit 0

View file

@ -0,0 +1,50 @@
#!/bin/bash
# Install "Verae Timestamping" as a CUPS destination (Print → Destination list).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
BIN="${VERAE_PRINT_BIN:-$HOME/bin/verae-print}"
BACKEND_SRC="$(cd "$(dirname "$0")" && pwd)/backend-verae.sh"
BACKEND_DST="/usr/libexec/cups/backend/verae"
QUEUE="Verae_Timestamping"
DISPLAY_NAME="Verae Timestamping"
if [[ ! -x "$BIN" ]]; then
echo "Building verae-print → $BIN"
mkdir -p "$(dirname "$BIN")"
(cd "$ROOT" && go build -o "$BIN" ./cmd/verae-print)
fi
if [[ ! -f "$BACKEND_SRC" ]]; then
echo "missing $BACKEND_SRC" >&2
exit 1
fi
echo "Installing CUPS backend → $BACKEND_DST"
TMP="$(mktemp)"
sed "s|/Users/marchon/bin/verae-print|$BIN|g" "$BACKEND_SRC" >"$TMP"
install -o root -g wheel -m 700 "$TMP" "$BACKEND_DST"
rm -f "$TMP"
# Device discovery check
"$BACKEND_DST" || true
lpstat -p "$QUEUE" &>/dev/null && lpadmin -x "$QUEUE" || true
# Raw queue: macOS print pipeline usually delivers PDF to the backend
lpadmin -p "$QUEUE" \
-E \
-v "verae:/" \
-D "$DISPLAY_NAME" \
-L "Digests-only Verae timestamp" \
-o printer-is-shared=false \
-m raw
cupsenable "$QUEUE" || true
cupsaccept "$QUEUE" || true
echo "Installed printer queue: $QUEUE ($DISPLAY_NAME)"
lpstat -v "$QUEUE" || true
echo
echo "In any app: Print → Destination → Verae Timestamping → Print"
echo "Outputs: ~/Documents/Verae Timestamps/{name}.pdf and {name}-verae-timestamp-{RECEIPTID}.pdf"

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.verae.timestamping.ipp</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/ippeveprinter</string>
<string>-c</string>
<string>/Users/SHARED_PLACEHOLDER/verae-print-command.sh</string>
<string>-d</string>
<string>/Users/SHARED_PLACEHOLDER/spool</string>
<string>-f</string>
<string>application/pdf,application/postscript</string>
<string>-p</string>
<string>8631</string>
<string>-n</string>
<string>localhost</string>
<string>-M</string>
<string>Verae</string>
<string>-m</string>
<string>Timestamping</string>
<string>-l</string>
<string>Digests-only timestamp</string>
<string>--no-web-forms</string>
<string>Verae Timestamping</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/SHARED_PLACEHOLDER/ippeveprinter.log</string>
<key>StandardErrorPath</key>
<string>/Users/SHARED_PLACEHOLDER/ippeveprinter.log</string>
</dict>
</plist>

View file

@ -0,0 +1,65 @@
#!/bin/bash
# Advertise "Verae Timestamping" via ippeveprinter (shows in Print → Destination).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
BIN="${VERAE_PRINT_BIN:-$HOME/bin/verae-print}"
SUPPORT="$HOME/Library/Application Support/Verae/ipp-printer"
CMD="$SUPPORT/verae-print-command.sh"
PLIST_SRC="$(cd "$(dirname "$0")" && pwd)/com.verae.timestamping.ipp.plist"
LAUNCH_AGENTS="$HOME/Library/LaunchAgents"
PLIST_DST="$LAUNCH_AGENTS/com.verae.timestamping.ipp.plist"
if [[ ! -x "$BIN" ]]; then
mkdir -p "$(dirname "$BIN")"
(cd "$ROOT" && go build -o "$BIN" ./cmd/verae-print)
fi
mkdir -p "$SUPPORT/spool" "$LAUNCH_AGENTS"
cp "$(cd "$(dirname "$0")" && pwd)/verae-print-command.sh" "$CMD"
chmod 755 "$CMD"
# Bake binary path
sed -i '' "s|VERAE_PRINT_BIN:-\$HOME/bin/verae-print|VERAE_PRINT_BIN:-$BIN|" "$CMD" 2>/dev/null || true
# Materialize LaunchAgent with user paths
sed "s|/Users/SHARED_PLACEHOLDER|$SUPPORT|g" "$PLIST_SRC" >"$PLIST_DST"
# Stop previous
launchctl bootout "gui/$(id -u)/com.verae.timestamping.ipp" 2>/dev/null || true
launchctl unload "$PLIST_DST" 2>/dev/null || true
# Remove broken CUPS raw/generic queue if present
lpstat -p Verae_Timestamping &>/dev/null && lpadmin -x Verae_Timestamping || true
# Remove unsigned custom backend if present (optional)
if [[ -f /usr/libexec/cups/backend/verae ]]; then
rm -f /usr/libexec/cups/backend/verae || true
fi
launchctl bootstrap "gui/$(id -u)" "$PLIST_DST" 2>/dev/null \
|| launchctl load -w "$PLIST_DST"
sleep 1
# Also register explicit CUPS queue pointing at local IPP (helps some apps)
if curl -sf -o /dev/null --max-time 2 "http://127.0.0.1:8631/" || true; then
lpadmin -p Verae_Timestamping -E \
-v "ipp://127.0.0.1:8631/ipp/print" \
-D "Verae Timestamping" \
-L "Digests-only Verae timestamp" \
-m everywhere 2>/dev/null \
|| lpadmin -p Verae_Timestamping -E \
-v "ipp://localhost:8631/ipp/print" \
-D "Verae Timestamping" \
-m everywhere || true
cupsenable Verae_Timestamping 2>/dev/null || true
cupsaccept Verae_Timestamping 2>/dev/null || true
fi
echo "Verae Timestamping IPP printer installed."
echo "LaunchAgent: $PLIST_DST"
echo "Command: $CMD"
echo "Check: lpstat -p -d ; lpstat -v"
lpstat -p Verae_Timestamping 2>/dev/null || true
lpstat -v Verae_Timestamping 2>/dev/null || true
echo
echo "Print → Destination → Verae Timestamping"
echo "Saves to ~/Documents/Verae Timestamps/"

View file

@ -0,0 +1,55 @@
#!/bin/bash
# ippeveprinter -c handler: PDF (or PS) on stdin → Verae stamp with approved naming.
set -euo pipefail
LOG="${HOME}/Library/Logs/verae-print-ipp.log"
mkdir -p "$(dirname "$LOG")"
exec >>"$LOG" 2>&1
echo "$(date -u +%Y-%m-%dT%H:%MZ) IPP job start env=$(env | grep -E '^IPP_|^CONTENT_|^USER=' | tr '\n' ' ')"
VERAE_PRINT="${VERAE_PRINT_BIN:-$HOME/bin/verae-print}"
CHANNEL="${VERAE_PRINT_CHANNEL:-verae}"
OUT_DIR="${HOME}/Documents/Verae Timestamps"
mkdir -p "$OUT_DIR"
TITLE="${IPP_JOB_NAME:-${IPP_DOCUMENT_NAME:-document}}"
# Strip path / extension for stem
BASE="$(basename "$TITLE")"
STEM="${BASE%.*}"
STEM="$(echo "$STEM" | tr -cd 'A-Za-z0-9._ -' | head -c 80)"
STEM="${STEM:-document}"
TMPDIR="${TMPDIR:-/tmp}"
WORK="$(mktemp -d "${TMPDIR}/verae-ipp.XXXXXX")"
RAW="$WORK/job.bin"
PDF="$WORK/${STEM}.pdf"
# ippeveprinter may pass a spool file as argv[1], or feed bytes on stdin
if [[ $# -ge 1 && -f "${1:-}" ]]; then
echo "input file arg: $1"
cp "$1" "$RAW"
elif [[ ! -t 0 ]]; then
cat >"$RAW"
else
echo "ERROR: no document on stdin or argv" >&2
exit 1
fi
if [[ ! -s "$RAW" ]]; then
echo "ERROR: empty document" >&2
exit 1
fi
if [[ "$(head -c 4 "$RAW")" == "%PDF" ]]; then
cp "$RAW" "$PDF"
elif command -v /usr/bin/pstopdf >/dev/null 2>&1; then
/usr/bin/pstopdf "$RAW" -o "$PDF" || cp "$RAW" "$PDF"
else
cp "$RAW" "$PDF"
fi
echo "stamping stem=$STEM channel=$CHANNEL pdf=$PDF"
"$VERAE_PRINT" stamp -channel "$CHANNEL" -out-dir "$OUT_DIR" -name "$STEM" -open "$PDF"
echo "ATTR: job-impressions-completed=1" >&2
rm -rf "$WORK"
exit 0