Initial commit: Meshkee dashboards monorepo.

Includes business, customer, and super-admin apps with shared packages and production deploy scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-07-22 13:48:53 +03:30
co-authored by Cursor
commit f566387c61
509 changed files with 62690 additions and 0 deletions
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
# Sync Let's Encrypt cert SANs with dashboard hosts from the API.
# Cron: 0 */2 * * * /opt/meshkee/dashboards/scripts/ssl-sync.sh >> /var/log/meshkee-ssl-sync.log 2>&1
set -euo pipefail
CONF=/etc/meshkee/ssl-sync.env
# shellcheck disable=SC1090
source "$CONF"
API_URL="${SSL_SYNC_API_URL:-https://api.meshkee.com/api/v1/internal/ssl/hosts}"
CERT_NAME="${SSL_CERT_NAME:-meshkee-dashboards}"
EMAIL="${SSL_EMAIL:-info@meshkee.com}"
WEBROOT="${SSL_WEBROOT:-/var/www/certbot}"
mkdir -p "$WEBROOT"
if [[ -z "${SSL_SYNC_TOKEN:-}" ]]; then
echo "$(date -Is) ERROR: SSL_SYNC_TOKEN not set in $CONF"
exit 1
fi
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT
HTTP_CODE=$(curl -sS -o "$TMP" -w '%{http_code}' \
-H "X-SSL-Sync-Token: ${SSL_SYNC_TOKEN}" \
"$API_URL")
if [[ "$HTTP_CODE" != "200" ]]; then
echo "$(date -Is) ERROR: API returned HTTP $HTTP_CODE"
cat "$TMP" || true
exit 1
fi
mapfile -t HOSTS < <(python3 -c '
import json, sys
data = json.load(open(sys.argv[1]))
for h in data.get("hosts") or []:
h = str(h).strip().lower()
if h:
print(h)
' "$TMP")
if [[ ${#HOSTS[@]} -eq 0 ]]; then
echo "$(date -Is) ERROR: empty host list from API"
exit 1
fi
# Always ensure admin + bootstrap tenant exist even if DB empty
EXTRA_HOSTS=(manage.meshkee.com business.sanihome.ir customer.sanihome.ir)
declare -A SEEN=()
FINAL=()
for h in "${HOSTS[@]}" "${EXTRA_HOSTS[@]}"; do
[[ -n "${SEEN[$h]:-}" ]] && continue
SEEN[$h]=1
FINAL+=("$h")
done
LIVE_DIR="/etc/letsencrypt/live/${CERT_NAME}"
NEED_ISSUE=0
if [[ ! -f "${LIVE_DIR}/fullchain.pem" ]]; then
NEED_ISSUE=1
else
CURRENT=$(openssl x509 -in "${LIVE_DIR}/fullchain.pem" -noout -text \
| awk '/DNS:/{gsub(/DNS:/,""); gsub(/,/, "\n"); print}' \
| tr -d ' ' | tr '[:upper:]' '[:lower:]' | sort -u)
for h in "${FINAL[@]}"; do
if ! grep -qxF "$h" <<<"$CURRENT"; then
NEED_ISSUE=1
break
fi
done
fi
if [[ "$NEED_ISSUE" -eq 0 ]]; then
echo "$(date -Is) OK: cert covers ${#FINAL[@]} hosts"
exit 0
fi
echo "$(date -Is) Expanding cert for: ${FINAL[*]}"
ARGS=(-d)
ARGS=()
for h in "${FINAL[@]}"; do
ARGS+=(-d "$h")
done
certbot certonly \
--webroot -w "$WEBROOT" \
--cert-name "$CERT_NAME" \
--email "$EMAIL" \
--agree-tos \
--non-interactive \
--expand \
"${ARGS[@]}"
nginx -t && systemctl reload nginx
echo "$(date -Is) Cert updated and nginx reloaded"