Files
osmap_cli/osmap-embed.sh
T

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