841 lines
33 KiB
Bash
841 lines
33 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# ==============================================================================
|
|
# OSMAP Embed Map & Token CLI (Multi-Domain Support)
|
|
# ==============================================================================
|
|
# Supports:
|
|
# 1. New Share-Map System -> app.osmap.id (API: api.osmap.id/apps/token/share-map)
|
|
# 2. OSMAP KAI System -> live.osmap.id & beta.osmap.id (API: /api/apps/token)
|
|
# ==============================================================================
|
|
|
|
set -e
|
|
|
|
# Color definitions
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
YELLOW='\033[1;33m'
|
|
MAGENTA='\033[0;35m'
|
|
BOLD='\033[1m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Cache directory
|
|
CACHE_DIR="${HOME}/.cache/osmap"
|
|
mkdir -p "$CACHE_DIR"
|
|
|
|
# Config file for saved credentials
|
|
CONFIG_FILE=".osmap_credentials"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 1. NEW SHARE-MAP SYSTEM (app.osmap.id)
|
|
# ------------------------------------------------------------------------------
|
|
APP_OSMAP_DOMAIN="app.osmap.id"
|
|
APP_OSMAP_API="https://api.osmap.id"
|
|
SHARE_MAP_EXPIRES_IN=86400
|
|
|
|
# Share Map Presets: "Key|Map_ID|Name|App_ID|App_Secret|Description"
|
|
SHARE_MAP_PRESETS=(
|
|
"accelerometer|94|Map Accelerometer|6f728437e6c4d361fb811913b8acd70e|ab9419a7fed7c51a6ff6daf501d408f2aed25c0ccd148a6c18b76f54949f55d8|Accelerometer Vibration & Track Monitoring"
|
|
"rocc|46|Map ROCC|6f728437e6c4d361fb811913b8acd70e|ab9419a7fed7c51a6ff6daf501d408f2aed25c0ccd148a6c18b76f54949f55d8|Railway Operations Control Center"
|
|
"genset|74|Map Genset|6f728437e6c4d361fb811913b8acd70e|ab9419a7fed7c51a6ff6daf501d408f2aed25c0ccd148a6c18b76f54949f55d8|Genset & Power Telemetry Monitoring"
|
|
"rcs|72|Map RCS|6f728437e6c4d361fb811913b8acd70e|ab9419a7fed7c51a6ff6daf501d408f2aed25c0ccd148a6c18b76f54949f55d8|Railway Cargo System Monitoring"
|
|
"jpl|70|Map JPL|2ee1aa4876f6b7fa3c43c75ca1c83139|073d0929a74bb664c402de98d24153c1f9f2f648d59c381f2fef3c32610fa174|Perlintasan Sebidang (JPL) Monitoring"
|
|
)
|
|
SHARE_FALLBACK_APP_ID="6f728437e6c4d361fb811913b8acd70e"
|
|
SHARE_FALLBACK_APP_SECRET="ab9419a7fed7c51a6ff6daf501d408f2aed25c0ccd148a6c18b76f54949f55d8"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 2. OSMAP KAI SYSTEM (live.osmap.id & beta.osmap.id)
|
|
# ------------------------------------------------------------------------------
|
|
DEFAULT_KAI_ENV="live"
|
|
DEFAULT_KAI_APP_ID="IrSIcf06QRwUCmsRCZ0JvsVibSfuPUG4"
|
|
DEFAULT_KAI_APP_SECRET="Z8tPOBHGbwWu9TrIddRqkiDFDymtiPAhMNbSz6aUOOTkqdZoQYuTWXTra5m2mPQa"
|
|
|
|
KAI_ROUTES=(
|
|
"executive|Executive Map|/executive"
|
|
"rolling|Rolling Map|/rolling"
|
|
"iris-jpl|IRIS JPL|/iris-jpl"
|
|
"iris-jpl-v2|IRIS JPL (v2)|/v2/iris-jpl"
|
|
"kai-accelerometer|Executive Accelerometer|/executive/accelerometer"
|
|
"kai-genset|Genset Monitoring|/genset"
|
|
"managerial|Managerial / Asset View|/managerial"
|
|
"fatigue|Fatigue Monitoring|/fatigue"
|
|
"sigap-tracker|SIGAP Tracker|/sigap-tracker"
|
|
"sigap-dashboard|SIGAP Dashboard|/sigap-dashboard"
|
|
"kai-rcs|Railway Cargo System (RCS)|/railway-cargo-system"
|
|
)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Common Utilities
|
|
# ------------------------------------------------------------------------------
|
|
copy_to_clipboard() {
|
|
local text="$1"
|
|
if command -v pbcopy >/dev/null 2>&1; then
|
|
echo -n "$text" | pbcopy
|
|
return 0
|
|
elif command -v xclip >/dev/null 2>&1; then
|
|
echo -n "$text" | xclip -selection clipboard
|
|
return 0
|
|
elif command -v xsel >/dev/null 2>&1; then
|
|
echo -n "$text" | xsel --clipboard --input
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
open_url() {
|
|
local url="$1"
|
|
if command -v open >/dev/null 2>&1; then
|
|
open "$url"
|
|
elif command -v xdg-open >/dev/null 2>&1; then
|
|
xdg-open "$url" >/dev/null 2>&1 &
|
|
elif command -v start >/dev/null 2>&1; then
|
|
start "$url"
|
|
else
|
|
echo -e "${YELLOW}Could not detect browser launcher. URL:${NC} $url"
|
|
fi
|
|
}
|
|
|
|
read_input() {
|
|
if [[ -t 0 ]]; then
|
|
read "$@"
|
|
elif [[ -e /dev/tty ]]; then
|
|
read "$@" < /dev/tty
|
|
else
|
|
read "$@"
|
|
fi
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# KAI Token Helpers (live / beta / local)
|
|
# ------------------------------------------------------------------------------
|
|
get_kai_base_url() {
|
|
local env="$1"
|
|
case "$env" in
|
|
live) echo "https://live.osmap.id" ;;
|
|
beta) echo "https://beta.osmap.id" ;;
|
|
local) echo "http://localhost:8000" ;;
|
|
demo) echo "https://demo.osmap.id" ;;
|
|
http*://*) echo "$env" ;;
|
|
*) echo "https://${env}" ;;
|
|
esac
|
|
}
|
|
|
|
get_kai_cache_file() {
|
|
local base_url="$1"
|
|
local sanitized
|
|
sanitized=$(echo "$base_url" | tr -d ':/' | tr '.' '_')
|
|
echo "${CACHE_DIR}/kai_token_${sanitized}.json"
|
|
}
|
|
|
|
get_valid_kai_token() {
|
|
local base_url="$1"
|
|
local app_id="$2"
|
|
local app_secret="$3"
|
|
local cache_file
|
|
cache_file=$(get_kai_cache_file "$base_url")
|
|
|
|
if [[ -f "$cache_file" ]]; then
|
|
local token expires_at
|
|
token=$(jq -r '.access_token // empty' "$cache_file" 2>/dev/null || true)
|
|
expires_at=$(jq -r '.expires_at // empty' "$cache_file" 2>/dev/null || true)
|
|
|
|
if [[ -n "$token" && -n "$expires_at" ]]; then
|
|
local expiry_epoch=0
|
|
if date -j -f "%Y-%m-%dT%H:%M:%S" "${expires_at:0:19}" +%s >/dev/null 2>&1; then
|
|
expiry_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${expires_at:0:19}" +%s)
|
|
elif date -d "$expires_at" +%s >/dev/null 2>&1; then
|
|
expiry_epoch=$(date -d "$expires_at" +%s)
|
|
fi
|
|
|
|
local now_epoch
|
|
now_epoch=$(date +%s)
|
|
if [[ $expiry_epoch -gt $((now_epoch + 60)) ]]; then
|
|
echo "$token"
|
|
return 0
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Fetch new KAI token
|
|
local endpoint="${base_url}/api/apps/token"
|
|
local payload
|
|
payload=$(jq -n --arg aid "$app_id" --arg asec "$app_secret" '{app_id: $aid, app_secret: $asec, expires_in_hours: 24}')
|
|
|
|
local response
|
|
response=$(curl -s --location "$endpoint" -H "Content-Type: application/json" -d "$payload")
|
|
|
|
local token
|
|
token=$(echo "$response" | jq -r '.access_token // empty' 2>/dev/null || true)
|
|
if [[ -z "$token" ]]; then
|
|
local err_msg
|
|
err_msg=$(echo "$response" | jq -r '.message // "Failed to obtain KAI token"' 2>/dev/null || echo "$response")
|
|
echo -e "${RED}Error fetching KAI token from ${base_url}:${NC} $err_msg" >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "$response" > "$cache_file"
|
|
chmod 600 "$cache_file"
|
|
echo "$token"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Share Map Helpers (app.osmap.id)
|
|
# ------------------------------------------------------------------------------
|
|
get_share_cache_file() {
|
|
local map_id="$1"
|
|
echo "${CACHE_DIR}/map_${map_id}.json"
|
|
}
|
|
|
|
generate_share_token() {
|
|
local map_id="$1"
|
|
local app_id="$2"
|
|
local app_secret="$3"
|
|
local expires_in="${4:-$SHARE_MAP_EXPIRES_IN}"
|
|
local force_fresh="${5:-false}"
|
|
|
|
if [[ "$force_fresh" != "true" ]]; then
|
|
local cache_file
|
|
cache_file=$(get_share_cache_file "$map_id")
|
|
if [[ -f "$cache_file" ]]; then
|
|
local token expires_at
|
|
token=$(jq -r '.token // empty' "$cache_file" 2>/dev/null || true)
|
|
expires_at=$(jq -r '.expires_at // empty' "$cache_file" 2>/dev/null || true)
|
|
|
|
if [[ -n "$token" && -n "$expires_at" ]]; then
|
|
local expiry_epoch=0
|
|
if date -j -f "%Y-%m-%dT%H:%M:%S" "${expires_at:0:19}" +%s >/dev/null 2>&1; then
|
|
expiry_epoch=$(date -j -f "%Y-%m-%dT%H:%M:%S" "${expires_at:0:19}" +%s)
|
|
elif date -d "$expires_at" +%s >/dev/null 2>&1; then
|
|
expiry_epoch=$(date -d "$expires_at" +%s)
|
|
fi
|
|
local now_epoch
|
|
now_epoch=$(date +%s)
|
|
if [[ $expiry_epoch -gt $((now_epoch + 60)) ]]; then
|
|
echo "$token"
|
|
return 0
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
local endpoint="${APP_OSMAP_API}/apps/token/share-map"
|
|
local payload
|
|
payload=$(jq -n \
|
|
--arg aid "$app_id" \
|
|
--arg asec "$app_secret" \
|
|
--argjson exp "$expires_in" \
|
|
--argjson mid "$map_id" \
|
|
'{app_id: $aid, app_secret: $asec, expires_in: $exp, map_id: $mid}')
|
|
|
|
local response
|
|
response=$(curl -s -X POST "$endpoint" -H "Content-Type: application/json" -d "$payload")
|
|
|
|
local is_success token
|
|
is_success=$(echo "$response" | jq -r '.status // .success // false' 2>/dev/null || echo "false")
|
|
token=$(echo "$response" | jq -r '.data.token // .token // empty' 2>/dev/null || true)
|
|
|
|
# Automatic fallback if first attempt lacked permissions
|
|
if [[ ("$is_success" != "true" || -z "$token") && "$app_id" != "$SHARE_FALLBACK_APP_ID" ]]; then
|
|
local error_code
|
|
error_code=$(echo "$response" | jq -r '.code // empty' 2>/dev/null || true)
|
|
if [[ "$error_code" == "SHARE_MAP_NO_PERMISSION" || "$error_code" == "UNAUTHORIZED" ]]; then
|
|
payload=$(jq -n \
|
|
--arg aid "$SHARE_FALLBACK_APP_ID" \
|
|
--arg asec "$SHARE_FALLBACK_APP_SECRET" \
|
|
--argjson exp "$expires_in" \
|
|
--argjson mid "$map_id" \
|
|
'{app_id: $aid, app_secret: $asec, expires_in: $exp, map_id: $mid}')
|
|
|
|
response=$(curl -s -X POST "$endpoint" -H "Content-Type: application/json" -d "$payload")
|
|
is_success=$(echo "$response" | jq -r '.status // .success // false' 2>/dev/null || echo "false")
|
|
token=$(echo "$response" | jq -r '.data.token // .token // empty' 2>/dev/null || true)
|
|
fi
|
|
fi
|
|
|
|
if [[ "$is_success" != "true" || -z "$token" ]]; then
|
|
local error_msg
|
|
error_msg=$(echo "$response" | jq -r '.message // "Failed to generate share-map token"' 2>/dev/null || echo "$response")
|
|
echo -e "${RED}Error generating share token for Map ${map_id}:${NC} $error_msg" >&2
|
|
return 1
|
|
fi
|
|
|
|
local cache_file
|
|
cache_file=$(get_share_cache_file "$map_id")
|
|
local expires_at
|
|
expires_at=$(echo "$response" | jq -r '.data.expires_at // empty' 2>/dev/null || true)
|
|
jq -n \
|
|
--arg token "$token" \
|
|
--argjson map_id "$map_id" \
|
|
--arg expires_at "$expires_at" \
|
|
'{token: $token, map_id: $map_id, expires_at: $expires_at}' > "$cache_file"
|
|
chmod 600 "$cache_file"
|
|
|
|
echo "$token"
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Display Functions
|
|
# ------------------------------------------------------------------------------
|
|
display_share_map() {
|
|
local key="$1"
|
|
local map_id="$2"
|
|
local name="$3"
|
|
local app_id="$4"
|
|
local app_secret="$5"
|
|
local desc="$6"
|
|
local auto_open="$7"
|
|
local auto_copy="$8"
|
|
local show_iframe="$9"
|
|
|
|
echo -e "${CYAN}Generating share token for ${BOLD}${name}${NC}${CYAN} (Map ID: ${map_id})...${NC}"
|
|
local token
|
|
if ! token=$(generate_share_token "$map_id" "$app_id" "$app_secret" "$SHARE_MAP_EXPIRES_IN" "false"); then
|
|
return 1
|
|
fi
|
|
|
|
local embed_url="https://${APP_OSMAP_DOMAIN}/maps/embed/${map_id}?token=${token}"
|
|
local iframe_code="<iframe src=\"${embed_url}\" width=\"100%\" height=\"600\" frameborder=\"0\" allowfullscreen></iframe>"
|
|
|
|
echo ""
|
|
echo -e "${BOLD}${GREEN}✔ ${name}${NC} (Map ID: ${BOLD}${map_id}${NC})"
|
|
if [[ -n "$desc" ]]; then
|
|
echo -e " ${YELLOW}Description:${NC} ${desc}"
|
|
fi
|
|
echo -e " ${BOLD}${CYAN}Embed URL:${NC} ${embed_url}"
|
|
echo -e " ${BOLD}${MAGENTA}Token:${NC} ${token}"
|
|
|
|
if [[ "$show_iframe" == "true" ]]; then
|
|
echo -e " ${BOLD}${YELLOW}Iframe Code:${NC}"
|
|
echo " ${iframe_code}"
|
|
fi
|
|
echo ""
|
|
|
|
if [[ "$auto_copy" == "true" ]]; then
|
|
if copy_to_clipboard "$embed_url"; then
|
|
echo -e " ${GREEN}✓ Copied Embed URL to clipboard!${NC}"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$auto_open" == "true" ]]; then
|
|
echo -e " ${CYAN}Opening in browser...${NC}"
|
|
open_url "$embed_url"
|
|
fi
|
|
}
|
|
|
|
display_kai_map() {
|
|
local name="$1"
|
|
local path="$2"
|
|
local base_url="$3"
|
|
local app_id="$4"
|
|
local app_secret="$5"
|
|
local auto_open="$6"
|
|
local auto_copy="$7"
|
|
|
|
echo -e "${CYAN}Retrieving token for ${base_url}...${NC}"
|
|
local token
|
|
if ! token=$(get_valid_kai_token "$base_url" "$app_id" "$app_secret"); then
|
|
return 1
|
|
fi
|
|
|
|
local full_url="${base_url}${path}?token=${token}"
|
|
|
|
echo ""
|
|
echo -e "${BOLD}${GREEN}✔ ${name}${NC} (${base_url})"
|
|
echo -e " ${BOLD}${CYAN}Embed URL:${NC} ${full_url}"
|
|
echo -e " ${BOLD}${MAGENTA}Token:${NC} ${token}"
|
|
echo ""
|
|
|
|
if [[ "$auto_copy" == "true" ]]; then
|
|
if copy_to_clipboard "$full_url"; then
|
|
echo -e " ${GREEN}✓ Copied URL to clipboard!${NC}"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$auto_open" == "true" ]]; then
|
|
echo -e " ${CYAN}Opening in browser...${NC}"
|
|
open_url "$full_url"
|
|
fi
|
|
}
|
|
|
|
print_all_curls() {
|
|
echo ""
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo -e "${BOLD}${CYAN} OSMAP cURL Reference (All Domains) ${NC}"
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo ""
|
|
echo -e "${BOLD}${YELLOW}--- 1. NEW SHARE-MAP SYSTEM (Domain: app.osmap.id) ---${NC}"
|
|
echo ""
|
|
local idx=1
|
|
for preset in "${SHARE_MAP_PRESETS[@]}"; do
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$preset"
|
|
echo -e "${BOLD}${GREEN}${idx}. ${name}${NC} (Map ID: ${map_id})"
|
|
cat << EOF
|
|
curl -X POST "https://api.osmap.id/apps/token/share-map" \\
|
|
-H "Content-Type: application/json" \\
|
|
-d '{"app_id":"${app_id}","app_secret":"${app_secret}","expires_in":86400,"map_id":${map_id}}'
|
|
EOF
|
|
echo ""
|
|
((idx++))
|
|
done
|
|
|
|
echo -e "${BOLD}${YELLOW}--- 2. OSMAP KAI SYSTEM (Domain: live.osmap.id) ---${NC}"
|
|
echo ""
|
|
cat << EOF
|
|
curl -X POST "https://live.osmap.id/api/apps/token" \\
|
|
-H "Content-Type: application/json" \\
|
|
-d '{"app_id":"${DEFAULT_KAI_APP_ID}","app_secret":"${DEFAULT_KAI_APP_SECRET}","expires_in_hours":24}'
|
|
EOF
|
|
echo ""
|
|
|
|
echo -e "${BOLD}${YELLOW}--- 3. OSMAP KAI SYSTEM (Domain: beta.osmap.id) ---${NC}"
|
|
echo ""
|
|
cat << EOF
|
|
curl -X POST "https://beta.osmap.id/api/apps/token" \\
|
|
-H "Content-Type: application/json" \\
|
|
-d '{"app_id":"${DEFAULT_KAI_APP_ID}","app_secret":"${DEFAULT_KAI_APP_SECRET}","expires_in_hours":24}'
|
|
EOF
|
|
echo ""
|
|
}
|
|
|
|
print_all_share_table() {
|
|
echo ""
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo -e "${BOLD}${CYAN} OSMAP Share Map Embed URLs (Domain: ${APP_OSMAP_DOMAIN}) ${NC}"
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo ""
|
|
printf "%-5s | %-20s | %s\n" "ID" "Map Name" "Embed URL with Token"
|
|
printf "%-5s-+-%-20s-+-%s\n" "-----" "--------------------" "----------------------------------------------------------------------------------"
|
|
|
|
for preset in "${SHARE_MAP_PRESETS[@]}"; do
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$preset"
|
|
local token
|
|
token=$(generate_share_token "$map_id" "$app_id" "$app_secret" "$SHARE_MAP_EXPIRES_IN" "false" 2>/dev/null || echo "")
|
|
if [[ -n "$token" ]]; then
|
|
printf "%-5s | %-20s | %s\n" "$map_id" "$name" "https://${APP_OSMAP_DOMAIN}/maps/embed/${map_id}?token=${token}"
|
|
else
|
|
printf "%-5s | %-20s | %s\n" "$map_id" "$name" "${RED}[Failed to generate token]${NC}"
|
|
fi
|
|
done
|
|
echo ""
|
|
}
|
|
|
|
print_all_kai_table() {
|
|
local env="${1:-live}"
|
|
local base_url
|
|
base_url=$(get_kai_base_url "$env")
|
|
echo ""
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo -e "${BOLD}${CYAN} OSMAP KAI Embed URLs (Domain / Base URL: ${base_url}) ${NC}"
|
|
echo -e "${BOLD}${CYAN}========================================================================================${NC}"
|
|
echo ""
|
|
local token
|
|
token=$(get_valid_kai_token "$base_url" "$DEFAULT_KAI_APP_ID" "$DEFAULT_KAI_APP_SECRET" 2>/dev/null || echo "")
|
|
if [[ -z "$token" ]]; then
|
|
echo -e "${RED}Failed to obtain valid token for ${base_url}${NC}"
|
|
return 1
|
|
fi
|
|
|
|
printf "%-30s | %s\n" "Map Feature" "Complete Embed URL"
|
|
printf "%-30s-+-%s\n" "------------------------------" "------------------------------------------------------------"
|
|
for item in "${KAI_ROUTES[@]}"; do
|
|
IFS="|" read -r key name path <<< "$item"
|
|
printf "%-30s | %s\n" "$name" "${base_url}${path}?token=${token}"
|
|
done
|
|
echo ""
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Interactive Menu
|
|
# ------------------------------------------------------------------------------
|
|
show_interactive_menu() {
|
|
local current_kai_env="$DEFAULT_KAI_ENV"
|
|
|
|
while true; do
|
|
local kai_base
|
|
kai_base=$(get_kai_base_url "$current_kai_env")
|
|
|
|
echo ""
|
|
echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════════════════════════════════════╗${NC}"
|
|
echo -e "${BOLD}${CYAN}║ OSMAP Universal Embed Map Navigator ║${NC}"
|
|
echo -e "${BOLD}${CYAN}╠══════════════════════════════════════════════════════════════════════════╣${NC}"
|
|
echo -e "${CYAN}║ 1. Share-Map Domain: ${BOLD}${YELLOW}${APP_OSMAP_DOMAIN}${NC}${CYAN} (API: api.osmap.id/apps/token/share-map)${NC}"
|
|
echo -e "${CYAN}║ 2. KAI Active Domain: ${BOLD}${YELLOW}${kai_base}${NC}${CYAN} (live.osmap.id / beta.osmap.id)${NC}"
|
|
echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════════════════════════════════════╝${NC}"
|
|
echo ""
|
|
|
|
echo -e "${BOLD}${YELLOW}─── [A] SHARE-MAP PRESETS (app.osmap.id) ───${NC}"
|
|
local idx=1
|
|
for preset in "${SHARE_MAP_PRESETS[@]}"; do
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$preset"
|
|
printf " ${BOLD}%2d)${NC} %-22s ${CYAN}(Map ID: %-2s)${NC} - %s\n" "$idx" "$name" "$map_id" "$desc"
|
|
((idx++))
|
|
done
|
|
|
|
echo ""
|
|
echo -e "${BOLD}${YELLOW}─── [B] OSMAP KAI ROUTES (${current_kai_env}: ${kai_base}) ───${NC}"
|
|
local kai_start=$idx
|
|
for item in "${KAI_ROUTES[@]}"; do
|
|
IFS="|" read -r key name path <<< "$item"
|
|
printf " ${BOLD}%2d)${NC} %-25s ${CYAN}%s${NC}\n" "$idx" "$name" "$path"
|
|
((idx++))
|
|
done
|
|
|
|
echo ""
|
|
echo -e "${BOLD}${YELLOW}─── [C] UTILITIES & SWITCH DOMAIN ───${NC}"
|
|
printf " ${BOLD}%2d)${NC} %s\n" "$idx" "Display All app.osmap.id Embed URLs Table"
|
|
local opt_table_share=$idx
|
|
((idx++))
|
|
printf " ${BOLD}%2d)${NC} %s\n" "$idx" "Display All KAI Embed URLs Table (${current_kai_env})"
|
|
local opt_table_kai=$idx
|
|
((idx++))
|
|
printf " ${BOLD}%2d)${NC} %s\n" "$idx" "Print All cURL Commands (app.osmap.id, live.osmap.id, beta.osmap.id)"
|
|
local opt_curls=$idx
|
|
((idx++))
|
|
printf " ${BOLD}%2d)${NC} %s\n" "$idx" "Switch KAI Environment (live / beta / local / custom URL)"
|
|
local opt_switch_env=$idx
|
|
((idx++))
|
|
printf " ${BOLD}%2d)${NC} %s\n" "$idx" "Custom Map ID (app.osmap.id)"
|
|
local opt_custom_mid=$idx
|
|
((idx++))
|
|
printf " ${BOLD} 0)${NC} %s\n" "Exit"
|
|
echo ""
|
|
|
|
read_input -r -p "Select an option [0-$((idx-1))]: " choice
|
|
|
|
if [[ "$choice" == "0" || "$choice" == "q" || "$choice" == "exit" ]]; then
|
|
echo -e "${GREEN}Goodbye!${NC}"
|
|
exit 0
|
|
fi
|
|
|
|
# Option: Share Map Presets (1..5)
|
|
if [[ "$choice" -ge 1 && "$choice" -le ${#SHARE_MAP_PRESETS[@]} ]]; then
|
|
local selected="${SHARE_MAP_PRESETS[$((choice-1))]}"
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$selected"
|
|
display_share_map "$key" "$map_id" "$name" "$app_id" "$app_secret" "$desc" "false" "true" "true"
|
|
|
|
echo ""
|
|
read_input -r -p "Open this map in default browser? (Y/n): " open_choice
|
|
if [[ ! "$open_choice" =~ ^[Nn]$ ]]; then
|
|
local token
|
|
token=$(generate_share_token "$map_id" "$app_id" "$app_secret" "$SHARE_MAP_EXPIRES_IN" "false")
|
|
open_url "https://${APP_OSMAP_DOMAIN}/maps/embed/${map_id}?token=${token}"
|
|
fi
|
|
|
|
# Option: KAI Routes
|
|
elif [[ "$choice" -ge "$kai_start" && "$choice" -lt "$opt_table_share" ]]; then
|
|
local kai_idx=$(( choice - kai_start ))
|
|
local selected_kai="${KAI_ROUTES[$kai_idx]}"
|
|
IFS="|" read -r key name path <<< "$selected_kai"
|
|
display_kai_map "$name" "$path" "$kai_base" "$DEFAULT_KAI_APP_ID" "$DEFAULT_KAI_APP_SECRET" "false" "true"
|
|
|
|
echo ""
|
|
read_input -r -p "Open this route in default browser? (Y/n): " open_choice
|
|
if [[ ! "$open_choice" =~ ^[Nn]$ ]]; then
|
|
local token
|
|
token=$(get_valid_kai_token "$kai_base" "$DEFAULT_KAI_APP_ID" "$DEFAULT_KAI_APP_SECRET")
|
|
open_url "${kai_base}${path}?token=${token}"
|
|
fi
|
|
|
|
elif [[ "$choice" -eq "$opt_table_share" ]]; then
|
|
print_all_share_table
|
|
elif [[ "$choice" -eq "$opt_table_kai" ]]; then
|
|
print_all_kai_table "$current_kai_env"
|
|
elif [[ "$choice" -eq "$opt_curls" ]]; then
|
|
print_all_curls
|
|
elif [[ "$choice" -eq "$opt_switch_env" ]]; then
|
|
echo ""
|
|
read_input -r -p "Enter environment [live, beta, local, demo, or custom URL]: " new_env
|
|
if [[ -n "$new_env" ]]; then
|
|
current_kai_env="$new_env"
|
|
echo -e "${GREEN}Switched KAI domain to:${NC} $(get_kai_base_url "$current_kai_env")"
|
|
fi
|
|
elif [[ "$choice" -eq "$opt_custom_mid" ]]; then
|
|
echo ""
|
|
read_input -r -p "Enter Map ID: " custom_mid
|
|
read_input -r -p "Enter App ID [Press Enter for default]: " custom_aid
|
|
read_input -r -p "Enter App Secret [Press Enter for default]: " custom_asec
|
|
|
|
custom_aid="${custom_aid:-$SHARE_FALLBACK_APP_ID}"
|
|
custom_asec="${custom_asec:-$SHARE_FALLBACK_APP_SECRET}"
|
|
|
|
if [[ -n "$custom_mid" ]]; then
|
|
display_share_map "custom" "$custom_mid" "Custom Map ${custom_mid}" "$custom_aid" "$custom_asec" "Custom Map ID" "false" "true" "true"
|
|
fi
|
|
else
|
|
echo -e "${RED}Invalid selection.${NC}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Help / Usage
|
|
# ------------------------------------------------------------------------------
|
|
show_help() {
|
|
cat << EOF
|
|
OSMAP Embed Map & Token CLI Tool (Multi-Domain)
|
|
|
|
Supported Domains & APIs:
|
|
1. app.osmap.id -> Share-Map API (https://api.osmap.id/apps/token/share-map)
|
|
2. live.osmap.id -> KAI App Token (https://live.osmap.id/api/apps/token)
|
|
3. beta.osmap.id -> KAI App Token (https://beta.osmap.id/api/apps/token)
|
|
|
|
Usage:
|
|
./osmap-embed.sh [command|map|route] [options]
|
|
|
|
Commands:
|
|
interactive Launch interactive navigator menu (default)
|
|
curls Display all cURL commands for app.osmap.id, live.osmap.id, beta.osmap.id
|
|
all Display embed URLs table for app.osmap.id (or with --env live/beta for KAI)
|
|
token <map|route> Generate and print only the token string
|
|
validate Validate KAI token
|
|
revoke Revoke KAI app token
|
|
|
|
Share Map Presets (app.osmap.id):
|
|
accelerometer | 94 Map Accelerometer (Map ID: 94)
|
|
rocc | 46 Map ROCC (Map ID: 46)
|
|
genset | 74 Map Genset (Map ID: 74)
|
|
rcs | 72 Map RCS (Map ID: 72)
|
|
jpl | 70 Map JPL (Map ID: 70)
|
|
|
|
KAI Routes (live.osmap.id / beta.osmap.id):
|
|
executive /executive
|
|
rolling /rolling
|
|
iris-jpl /iris-jpl
|
|
iris-jpl-v2 /v2/iris-jpl
|
|
kai-accelerometer /executive/accelerometer
|
|
kai-genset /genset
|
|
managerial /managerial
|
|
fatigue /fatigue
|
|
sigap-tracker /sigap-tracker
|
|
sigap-dashboard /sigap-dashboard
|
|
kai-rcs /railway-cargo-system
|
|
|
|
Options:
|
|
-e, --env <env> Environment for KAI: live (default), beta, local, or URL
|
|
--domain <domain> Override Share-Map domain (default: ${APP_OSMAP_DOMAIN})
|
|
--map-id <id> Specify custom Map ID for app.osmap.id
|
|
-o, --open Automatically open URL in default browser
|
|
-c, --copy Copy URL to clipboard
|
|
--iframe Show <iframe> embed HTML snippet
|
|
--fresh Bypass local cache and request fresh token
|
|
-h, --help Show this help message
|
|
|
|
Examples:
|
|
./osmap-embed.sh
|
|
./osmap-embed.sh curls
|
|
./osmap-embed.sh accelerometer --open
|
|
./osmap-embed.sh rocc -c
|
|
./osmap-embed.sh executive --env live --open
|
|
./osmap-embed.sh iris-jpl --env beta
|
|
./osmap-embed.sh all --env beta
|
|
EOF
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Argument Parsing
|
|
# ------------------------------------------------------------------------------
|
|
COMMAND_OR_TARGET=""
|
|
EXTRA_ARG=""
|
|
TARGET_ENV="$DEFAULT_KAI_ENV"
|
|
MAP_ID_ARG=""
|
|
APP_ID_OVERRIDE=""
|
|
APP_SECRET_OVERRIDE=""
|
|
AUTO_OPEN="false"
|
|
AUTO_COPY="false"
|
|
SHOW_IFRAME="false"
|
|
FORCE_FRESH="false"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-o|--open)
|
|
AUTO_OPEN="true"
|
|
shift
|
|
;;
|
|
-c|--copy)
|
|
AUTO_COPY="true"
|
|
shift
|
|
;;
|
|
--iframe)
|
|
SHOW_IFRAME="true"
|
|
shift
|
|
;;
|
|
--fresh)
|
|
FORCE_FRESH="true"
|
|
shift
|
|
;;
|
|
-e|--env)
|
|
TARGET_ENV="$2"
|
|
shift 2
|
|
;;
|
|
--domain|--app-domain)
|
|
APP_OSMAP_DOMAIN="$2"
|
|
shift 2
|
|
;;
|
|
--api-url)
|
|
APP_OSMAP_API="$2"
|
|
shift 2
|
|
;;
|
|
--map-id)
|
|
MAP_ID_ARG="$2"
|
|
shift 2
|
|
;;
|
|
--app-id)
|
|
APP_ID_OVERRIDE="$2"
|
|
shift 2
|
|
;;
|
|
--app-secret)
|
|
APP_SECRET_OVERRIDE="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
if [[ -z "$COMMAND_OR_TARGET" ]]; then
|
|
COMMAND_OR_TARGET="$1"
|
|
elif [[ -z "$EXTRA_ARG" ]]; then
|
|
EXTRA_ARG="$1"
|
|
fi
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Strip trailing slashes or protocols if passed
|
|
APP_OSMAP_DOMAIN=$(echo "$APP_OSMAP_DOMAIN" | sed -e 's|^https://||' -e 's|^http://||' -e 's|/$||')
|
|
APP_OSMAP_API=$(echo "$APP_OSMAP_API" | sed -e 's|/$||')
|
|
|
|
# Helper: Find Share Map preset
|
|
find_share_preset() {
|
|
local query="$1"
|
|
local idx=1
|
|
for preset in "${SHARE_MAP_PRESETS[@]}"; do
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$preset"
|
|
if [[ "$query" == "$key" || "$query" == "$map_id" ]]; then
|
|
echo "$preset"
|
|
return 0
|
|
fi
|
|
((idx++))
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Helper: Find KAI route
|
|
find_kai_route() {
|
|
local query="$1"
|
|
for item in "${KAI_ROUTES[@]}"; do
|
|
IFS="|" read -r key name path <<< "$item"
|
|
if [[ "$query" == "$key" || "$query" == "${path#/}" || "$query" == "$path" ]]; then
|
|
echo "$item"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Execution Dispatcher
|
|
if [[ -n "$MAP_ID_ARG" ]]; then
|
|
aid="${APP_ID_OVERRIDE:-$SHARE_FALLBACK_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$SHARE_FALLBACK_APP_SECRET}"
|
|
display_share_map "custom" "$MAP_ID_ARG" "Map ${MAP_ID_ARG}" "$aid" "$asec" "Custom Map ID" "$AUTO_OPEN" "$AUTO_COPY" "$SHOW_IFRAME"
|
|
exit 0
|
|
fi
|
|
|
|
case "$COMMAND_OR_TARGET" in
|
|
""|interactive)
|
|
show_interactive_menu
|
|
exit 0
|
|
;;
|
|
all)
|
|
if [[ "$TARGET_ENV" != "$DEFAULT_KAI_ENV" ]]; then
|
|
print_all_kai_table "$TARGET_ENV"
|
|
else
|
|
print_all_share_table
|
|
fi
|
|
exit 0
|
|
;;
|
|
curl|curls)
|
|
print_all_curls
|
|
exit 0
|
|
;;
|
|
token)
|
|
target="${EXTRA_ARG:-accelerometer}"
|
|
if share_found=$(find_share_preset "$target"); then
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$share_found"
|
|
aid="${APP_ID_OVERRIDE:-$app_id}"
|
|
asec="${APP_SECRET_OVERRIDE:-$app_secret}"
|
|
generate_share_token "$map_id" "$aid" "$asec" "$SHARE_MAP_EXPIRES_IN" "$FORCE_FRESH"
|
|
exit 0
|
|
elif kai_found=$(find_kai_route "$target"); then
|
|
base_url=$(get_kai_base_url "$TARGET_ENV")
|
|
aid="${APP_ID_OVERRIDE:-$DEFAULT_KAI_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$DEFAULT_KAI_APP_SECRET}"
|
|
get_valid_kai_token "$base_url" "$aid" "$asec"
|
|
exit 0
|
|
elif [[ "$target" =~ ^[0-9]+$ ]]; then
|
|
aid="${APP_ID_OVERRIDE:-$SHARE_FALLBACK_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$SHARE_FALLBACK_APP_SECRET}"
|
|
generate_share_token "$target" "$aid" "$asec" "$SHARE_MAP_EXPIRES_IN" "$FORCE_FRESH"
|
|
exit 0
|
|
else
|
|
echo -e "${RED}Unknown target:${NC} $target" >&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
validate)
|
|
base_url=$(get_kai_base_url "$TARGET_ENV")
|
|
cache_file=$(get_kai_cache_file "$base_url")
|
|
if [[ -f "$cache_file" ]]; then
|
|
tok=$(jq -r '.access_token // empty' "$cache_file" 2>/dev/null || true)
|
|
if [[ -n "$tok" ]]; then
|
|
echo -e "${GREEN}✓ Cached token exists for ${base_url}:${NC} $tok"
|
|
exit 0
|
|
fi
|
|
fi
|
|
echo -e "${RED}✗ No valid cached token found for ${base_url}${NC}"
|
|
exit 1
|
|
;;
|
|
revoke)
|
|
base_url=$(get_kai_base_url "$TARGET_ENV")
|
|
aid="${APP_ID_OVERRIDE:-$DEFAULT_KAI_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$DEFAULT_KAI_APP_SECRET}"
|
|
payload=$(jq -n --arg aid "$aid" --arg asec "$asec" '{app_id: $aid, app_secret: $asec}')
|
|
echo -e "${CYAN}Revoking tokens at ${base_url}/api/apps/revoke-tokens...${NC}"
|
|
curl -s -X POST "${base_url}/api/apps/revoke-tokens" -H "Content-Type: application/json" -d "$payload" | jq .
|
|
rm -f "$(get_kai_cache_file "$base_url")"
|
|
echo -e "${GREEN}Local cache cleared for ${base_url}.${NC}"
|
|
exit 0
|
|
;;
|
|
*)
|
|
# Check Share Map preset match
|
|
if share_found=$(find_share_preset "$COMMAND_OR_TARGET"); then
|
|
IFS="|" read -r key map_id name app_id app_secret desc <<< "$share_found"
|
|
aid="${APP_ID_OVERRIDE:-$app_id}"
|
|
asec="${APP_SECRET_OVERRIDE:-$app_secret}"
|
|
display_share_map "$key" "$map_id" "$name" "$aid" "$asec" "$desc" "$AUTO_OPEN" "$AUTO_COPY" "$SHOW_IFRAME"
|
|
exit 0
|
|
# Check KAI route match
|
|
elif kai_found=$(find_kai_route "$COMMAND_OR_TARGET"); then
|
|
IFS="|" read -r key name path <<< "$kai_found"
|
|
base_url=$(get_kai_base_url "$TARGET_ENV")
|
|
aid="${APP_ID_OVERRIDE:-$DEFAULT_KAI_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$DEFAULT_KAI_APP_SECRET}"
|
|
display_kai_map "$name" "$path" "$base_url" "$aid" "$asec" "$AUTO_OPEN" "$AUTO_COPY"
|
|
exit 0
|
|
# Check if number passed as map_id
|
|
elif [[ "$COMMAND_OR_TARGET" =~ ^[0-9]+$ ]]; then
|
|
aid="${APP_ID_OVERRIDE:-$SHARE_FALLBACK_APP_ID}"
|
|
asec="${APP_SECRET_OVERRIDE:-$SHARE_FALLBACK_APP_SECRET}"
|
|
display_share_map "custom" "$COMMAND_OR_TARGET" "Map ${COMMAND_OR_TARGET}" "$aid" "$asec" "Custom Map ID" "$AUTO_OPEN" "$AUTO_COPY" "$SHOW_IFRAME"
|
|
exit 0
|
|
else
|
|
echo -e "${RED}Unknown map, route, or command:${NC} $COMMAND_OR_TARGET"
|
|
echo "Run './osmap-embed.sh --help' for available maps and commands."
|
|
exit 1
|
|
fi
|
|
;;
|
|
esac
|