diff --git a/README.md b/README.md index fe05708..5f07e62 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,32 @@ Channels: - `verae` (default) — `api.veraetime.net` + JWT in `~/.verae/auth.properties` - `zapier` — `zap.verae.ai` + `xVerae-` + `attachPdf:true` +## Signed macOS installer (.pkg) + +Same FlightLookup Developer ID + notarization path as Verae Timestamping.app (`~/fie/installers/macos/signing.env`). + +```bash +cd /Users/marchon/research/PrintToVeraeTimeStamp +chmod +x platform/macos/pkg/build-pkg.sh +./platform/macos/pkg/build-pkg.sh +# → build/macos-pkg/dist/VeraePrintStamp-0.1.0.pkg +# → build/macos-pkg/dist/VeraePrintStamp-macos.pkg +``` + +The pkg installs: + +| Path | Role | +|------|------| +| `/Applications/Verae Print Stamp.app` | Drop / Open With | +| `/Library/Application Support/Verae/PrintStamp/bin/verae-print` | Stamp CLI (universal) | +| `/usr/local/bin/verae-print` | Symlink | +| LaunchAgent + CUPS queue | **Print → Destination → Verae Timestamping** | + +Requires: `Developer ID Application` + `Developer ID Installer` (FlightLookup), App Store Connect API key in `signing.env`, Node for bundling the registration PDF builder. + ## Status -macOS v0 (PDF Services) is implemented. CUPS virtual printer, Linux, and Windows remain per the [spec](docs/superpowers/specs/2026-10-03-print-to-verae-timestamp.md) and [plan](docs/superpowers/plans/2026-10-03-print-to-verae-timestamp.md). +macOS Destination printer + branded registration PDF work locally. Signed `.pkg` build script is under `platform/macos/pkg/`. Linux and Windows remain per the [spec](docs/superpowers/specs/2026-10-03-print-to-verae-timestamp.md) and [plan](docs/superpowers/plans/2026-10-03-print-to-verae-timestamp.md). ## Contributing diff --git a/platform/macos/pkg/build-pkg.sh b/platform/macos/pkg/build-pkg.sh new file mode 100755 index 0000000..02ad5a9 --- /dev/null +++ b/platform/macos/pkg/build-pkg.sh @@ -0,0 +1,177 @@ +#!/usr/bin/env bash +# Build a Developer ID–signed, notarized macOS .pkg for Verae Print Stamp. +# Uses the same signing.env as Verae Timestamping.app (FlightLookup Inc.). +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" +PKG_DIR="$(cd "$(dirname "$0")" && pwd)" +SIGNING_ENV="${SIGNING_ENV:-$HOME/fie/installers/macos/signing.env}" +# shellcheck source=/dev/null +source "$SIGNING_ENV" + +VERSION="${VERSION:-0.1.0}" +BUILD_ROOT="$ROOT/build/macos-pkg" +STAGE="$BUILD_ROOT/stage" +SCRIPTS="$BUILD_ROOT/scripts" +DIST="$BUILD_ROOT/dist" +ID_APP="${APPLE_APP_SIGN_ID:-Developer ID Application: FlightLookup Inc. (G8CKY7VMZC)}" +ID_PKG="${APPLE_INSTALLER_SIGN_ID:-Developer ID Installer: FlightLookup Inc. (G8CKY7VMZC)}" +ENTITLEMENTS="$PKG_DIR/entitlements.plist" +BUNDLE_ID="ai.verae.print-stamp" +PKG_ID="ai.verae.print-stamp.pkg" + +echo "→ Cleaning $BUILD_ROOT" +rm -rf "$BUILD_ROOT" +mkdir -p "$STAGE" "$SCRIPTS" "$DIST" \ + "$STAGE/Library/Application Support/Verae/PrintStamp/bin" \ + "$STAGE/Library/Application Support/Verae/PrintStamp/ipp" \ + "$STAGE/Library/Application Support/Verae/PrintStamp/registration-pdf" \ + "$STAGE/Applications" + +echo "→ Building universal verae-print $VERSION" +cd "$ROOT" +mkdir -p "$BUILD_ROOT/bin" +GOOS=darwin GOARCH=arm64 go build -o "$BUILD_ROOT/bin/verae-print-arm64" ./cmd/verae-print +GOOS=darwin GOARCH=amd64 go build -o "$BUILD_ROOT/bin/verae-print-amd64" ./cmd/verae-print +# Embed version string into HelperVersion via env for postinstall display +echo "$VERSION" > "$STAGE/Library/Application Support/Verae/PrintStamp/VERSION" +lipo -create -output "$STAGE/Library/Application Support/Verae/PrintStamp/bin/verae-print" \ + "$BUILD_ROOT/bin/verae-print-arm64" "$BUILD_ROOT/bin/verae-print-amd64" +chmod 755 "$STAGE/Library/Application Support/Verae/PrintStamp/bin/verae-print" + +echo "→ Signing verae-print" +codesign --force --sign "$ID_APP" --options runtime --timestamp \ + --entitlements "$ENTITLEMENTS" \ + "$STAGE/Library/Application Support/Verae/PrintStamp/bin/verae-print" + +echo "→ Bundling registration-pdf (jsPDF) + assets" +cp -R "$ROOT/platform/registration-pdf/." "$STAGE/Library/Application Support/Verae/PrintStamp/registration-pdf/" +rm -rf "$STAGE/Library/Application Support/Verae/PrintStamp/registration-pdf/node_modules" +( + cd "$STAGE/Library/Application Support/Verae/PrintStamp/registration-pdf" + npm ci --omit=dev 2>/dev/null || npm install --omit=dev +) +mkdir -p "$STAGE/Library/Application Support/Verae/PrintStamp/assets" +cp -f "$ROOT/assets/VeraeFullLogo.png" "$STAGE/Library/Application Support/Verae/PrintStamp/assets/" 2>/dev/null || true +cp -f "$ROOT/internal/pdfcert/logo.png" "$STAGE/Library/Application Support/Verae/PrintStamp/registration-pdf/VeraeFullLogo.png" 2>/dev/null || true + +echo "→ IPP helper files" +cp -f "$ROOT/platform/macos/ipp/verae-print-command.sh" "$STAGE/Library/Application Support/Verae/PrintStamp/ipp/" +cp -f "$ROOT/platform/macos/ipp/com.verae.timestamping.ipp.plist" "$STAGE/Library/Application Support/Verae/PrintStamp/ipp/" +chmod 755 "$STAGE/Library/Application Support/Verae/PrintStamp/ipp/verae-print-command.sh" +# Point LaunchAgent template -c path will be rewritten in postinstall to user support; +# also bake library binary path into a system copy of the command for reference. +sed -i '' "s|VERAE_PRINT_BIN:-\$HOME/bin/verae-print|VERAE_PRINT_BIN:-/Library/Application Support/Verae/PrintStamp/bin/verae-print|" \ + "$STAGE/Library/Application Support/Verae/PrintStamp/ipp/verae-print-command.sh" 2>/dev/null || true + +echo "→ Building Verae Print Stamp.app" +APP="$STAGE/Applications/Verae Print Stamp.app" +mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" +cat > "$APP/Contents/Info.plist" < + + + CFBundleExecutableVerae Print Stamp + CFBundleIdentifier$BUNDLE_ID + CFBundleNameVerae Print Stamp + CFBundleDisplayNameVerae Print Stamp + CFBundlePackageTypeAPPL + CFBundleShortVersionString$VERSION + CFBundleVersion$VERSION + LSMinimumSystemVersion14.0 + NSHighResolutionCapable + CFBundleDocumentTypes + + + CFBundleTypeNamePDF + CFBundleTypeRoleViewer + LSHandlerRankAlternate + LSItemContentTypes + com.adobe.pdf + + + NSHumanReadableCopyright + Copyright © FlightLookup Inc. / Verae + +PLIST + +cat > "$APP/Contents/MacOS/Verae Print Stamp" <<'RUN' +#!/bin/bash +BIN="/Library/Application Support/Verae/PrintStamp/bin/verae-print" +CHANNEL="${VERAE_PRINT_CHANNEL:-verae}" +if [[ $# -eq 0 ]]; then + osascript <<'OSA' +display dialog "Drop a PDF on this app, use Open With, or Print → Destination → Verae Timestamping." buttons {"OK"} default button 1 with title "Verae Print Stamp" +OSA + open -R "/Library/Application Support/Verae/PrintStamp" 2>/dev/null || true + exit 0 +fi +for f in "$@"; do + case "$f" in + *.pdf|*.PDF|*.html|*.HTML|*.htm|*.HTM) + "$BIN" stamp -channel "$CHANNEL" -open "$f" \ + || osascript -e "display notification \"Stamp failed for $(basename "$f")\" with title \"Verae Print Stamp\"" + ;; + *) + osascript -e "display notification \"Unsupported file: $(basename "$f")\" with title \"Verae Print Stamp\"" + ;; + esac +done +RUN +chmod 755 "$APP/Contents/MacOS/Verae Print Stamp" + +echo "→ Signing app bundle" +codesign --force --deep --sign "$ID_APP" --options runtime --timestamp \ + --entitlements "$ENTITLEMENTS" \ + "$APP" + +echo "→ Preparing pkg scripts" +cp -f "$PKG_DIR/scripts/postinstall" "$SCRIPTS/postinstall" +chmod 755 "$SCRIPTS/postinstall" + +COMPONENT_PKG="$DIST/VeraePrintStamp-component.pkg" +PRODUCT_PKG="$DIST/VeraePrintStamp-${VERSION}.pkg" + +echo "→ pkgbuild component" +pkgbuild \ + --root "$STAGE" \ + --scripts "$SCRIPTS" \ + --identifier "$PKG_ID" \ + --version "$VERSION" \ + --install-location "/" \ + "$COMPONENT_PKG" + +echo "→ productbuild + Developer ID Installer sign" +productbuild \ + --package "$COMPONENT_PKG" \ + --identity "$ID_PKG" \ + --timestamp \ + "$PRODUCT_PKG" + +echo "→ Notarizing $PRODUCT_PKG" +xcrun notarytool submit "$PRODUCT_PKG" --wait \ + --key "$APPLE_API_KEY_PATH" \ + --key-id "$APPLE_API_KEY_ID" \ + --issuer "$APPLE_API_ISSUER_ID" + +echo "→ Stapling" +xcrun stapler staple "$PRODUCT_PKG" + +echo "→ Verifying" +spctl -a -vv -t install "$PRODUCT_PKG" || true +pkgutil --check-signature "$PRODUCT_PKG" || true + +# Stable latest name + checksums +cp -f "$PRODUCT_PKG" "$DIST/VeraePrintStamp-macos.pkg" +( + cd "$DIST" + shasum -a 256 "VeraePrintStamp-${VERSION}.pkg" VeraePrintStamp-macos.pkg > SHA256SUMS +) + +echo +echo "Signed installable ready:" +echo " $PRODUCT_PKG" +echo " $DIST/VeraePrintStamp-macos.pkg" +echo +echo "Install: double-click the .pkg (or: sudo installer -pkg … -target /)" +echo "Then: Print → Destination → Verae Timestamping" diff --git a/platform/macos/pkg/entitlements.plist b/platform/macos/pkg/entitlements.plist new file mode 100644 index 0000000..3ed8964 --- /dev/null +++ b/platform/macos/pkg/entitlements.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.network.client + + com.apple.security.files.user-selected.read-write + + + diff --git a/platform/macos/pkg/scripts/postinstall b/platform/macos/pkg/scripts/postinstall new file mode 100755 index 0000000..13028bc --- /dev/null +++ b/platform/macos/pkg/scripts/postinstall @@ -0,0 +1,66 @@ +#!/bin/bash +# Install Verae Timestamping print destination for the console user. +set -euo pipefail + +LOG="/var/log/verae-print-pkg-postinstall.log" +exec >>"$LOG" 2>&1 +echo "$(date -u +%Y-%m-%dT%H:%MZ) postinstall start" + +BIN="/Library/Application Support/Verae/PrintStamp/bin/verae-print" +SUPPORT="/Library/Application Support/Verae/PrintStamp" +APP="/Applications/Verae Print Stamp.app" + +# Symlink CLI onto PATH +mkdir -p /usr/local/bin +ln -sf "$BIN" /usr/local/bin/verae-print + +# Install Destination printer for the logged-in GUI user +CONSOLE_USER=$(stat -f%Su /dev/console 2>/dev/null || true) +if [[ -z "$CONSOLE_USER" || "$CONSOLE_USER" == "root" || "$CONSOLE_USER" == "_mbsetupuser" ]]; then + CONSOLE_USER=$(scutil <<< "show State:/Users/ConsoleUser" 2>/dev/null | awk '/Name :/ && $3 != "loginwindow" { print $3 }' || true) +fi + +if [[ -n "${CONSOLE_USER:-}" && "$CONSOLE_USER" != "root" ]]; then + HOME_DIR=$(dscl . -read "/Users/$CONSOLE_USER" NFSHomeDirectory 2>/dev/null | awk '{print $2}') + if [[ -n "$HOME_DIR" && -d "$HOME_DIR" ]]; then + export HOME="$HOME_DIR" + export USER="$CONSOLE_USER" + export VERAE_PRINT_BIN="$BIN" + # Copy install script helpers into user support and run as that user + USER_SUPPORT="$HOME_DIR/Library/Application Support/Verae/ipp-printer" + mkdir -p "$USER_SUPPORT/spool" + cp -f "$SUPPORT/ipp/verae-print-command.sh" "$USER_SUPPORT/verae-print-command.sh" + chmod 755 "$USER_SUPPORT/verae-print-command.sh" + chown -R "$CONSOLE_USER" "$HOME_DIR/Library/Application Support/Verae" || true + + # Materialize LaunchAgent + PLIST_SRC="$SUPPORT/ipp/com.verae.timestamping.ipp.plist" + PLIST_DST="$HOME_DIR/Library/LaunchAgents/com.verae.timestamping.ipp.plist" + mkdir -p "$HOME_DIR/Library/LaunchAgents" + sed "s|/Users/SHARED_PLACEHOLDER|$USER_SUPPORT|g" "$PLIST_SRC" >"$PLIST_DST" + # Point -c at user command; bake verae-print path into command script + sed -i '' "s|VERAE_PRINT_BIN:-\$HOME/bin/verae-print|VERAE_PRINT_BIN:-$BIN|" "$USER_SUPPORT/verae-print-command.sh" 2>/dev/null || true + chown "$CONSOLE_USER" "$PLIST_DST" + + UID_NUM=$(id -u "$CONSOLE_USER") + launchctl bootout "gui/$UID_NUM/com.verae.timestamping.ipp" 2>/dev/null || true + sudo -u "$CONSOLE_USER" launchctl bootstrap "gui/$UID_NUM" "$PLIST_DST" 2>/dev/null \ + || sudo -u "$CONSOLE_USER" launchctl load -w "$PLIST_DST" 2>/dev/null \ + || true + + sleep 1 + # Register CUPS queue if IPP is up + if curl -sf -o /dev/null --max-time 2 "http://127.0.0.1:8631/" 2>/dev/null; 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 || true + cupsenable Verae_Timestamping 2>/dev/null || true + cupsaccept Verae_Timestamping 2>/dev/null || true + fi + fi +fi + +echo "$(date -u +%Y-%m-%dT%H:%MZ) postinstall done" +exit 0