#!/bin/bash # Shared helpers for the peer subsystem. Peers are named other LibrePortal # instances; rows live in the sqlite `peers` table (db_create_tables.sh). # # kind enum: # backup-channel Friendly label over a hostname that shows up in a # shared backup repo. No new networking — Phase 1/2. # direct-ssh-direct Reachable peer over plain SSH (Phase 3). # direct-ssh-via-relay Peer over Connect's blind relay (Phase 3b). # # config_json is kind-specific. For backup-channel: # {"hostname":"homelab","loc_idx":1} _peerDb() { echo "$docker_dir/$db_file"; } # Quote a value for SQLite (escape single quotes by doubling). Stdin in, # stdout out. Caller wraps the result in their own single quotes. peerSqlEscape() { local s="$1" printf "%s" "${s//\'/\'\'}" } # Validate that a string is a reasonable peer-name (alnum, dash, underscore, # dot; 1..64 chars). Echo "ok" or the rejection reason; caller checks for "ok". peerValidateName() { local name="$1" if [[ -z "$name" ]]; then echo "empty"; return 1; fi if [[ ${#name} -gt 64 ]]; then echo "too-long"; return 1; fi if [[ ! "$name" =~ ^[A-Za-z0-9._-]+$ ]]; then echo "invalid-chars"; return 1; fi echo "ok" } # Validate kind. backup-channel (Phase 1/2) and direct-ssh-direct (Phase 3) # are live; direct-ssh-via-relay needs Connect to exist (Phase 3b). peerValidateKind() { local kind="$1" case "$kind" in backup-channel|direct-ssh-direct) echo "ok" ;; direct-ssh-via-relay) echo "needs-connect"; return 1 ;; *) echo "unknown-kind"; return 1 ;; esac }