#!/bin/bash # Script de configuração interativa do Jitsi Meet para SGSE # Este script facilita a configuração inicial do Jitsi no sistema SGSE set -e # Cores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Variáveis DOMAIN="" APP_ID="" ROOM_PREFIX="" USE_HTTPS=false ACCEPT_SELF_SIGNED=false JWT_SECRET="" JWT_AUDIENCE="" JWT_ISSUER="" AMBIENTE="" TEST_ONLY=false VALIDATE_ONLY=false NON_INTERACTIVE=false # Função para imprimir mensagens print_info() { echo -e "${BLUE}ℹ️ $1${NC}" } print_success() { echo -e "${GREEN}✅ $1${NC}" } print_warning() { echo -e "${YELLOW}⚠️ $1${NC}" } print_error() { echo -e "${RED}❌ $1${NC}" } # Função para validar formato de domínio validar_dominio() { local dominio=$1 if [[ -z "$dominio" ]]; then return 1 fi # Padrão para localhost:porta if [[ $dominio =~ ^(localhost|127\.0\.0\.1|0\.0\.0\.0)(:[0-9]+)?$ ]]; then return 0 fi # Padrão para FQDN if [[ $dominio =~ ^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(:[0-9]+)?$ ]]; then return 0 fi return 1 } # Função para validar App ID validar_app_id() { local app_id=$1 if [[ -z "$app_id" ]]; then return 1 fi if [[ $app_id =~ ^[a-zA-Z0-9_-]+$ ]]; then return 0 fi return 1 } # Função para validar JWT Secret validar_jwt_secret() { local secret=$1 if [[ -z "$secret" ]]; then return 0 # Opcional fi if [[ ${#secret} -lt 16 ]]; then return 1 fi return 0 } # Função para testar conectividade testar_conectividade() { local dominio=$1 local use_https=$2 print_info "Testando conectividade com $dominio..." # Extrair host e porta local host=$(echo $dominio | cut -d: -f1) local porta=$(echo $dominio | cut -d: -f2) if [[ -z "$porta" ]]; then if [[ "$use_https" == "true" ]]; then porta=443 else porta=80 fi fi local protocol="http" if [[ "$use_https" == "true" ]]; then protocol="https" fi local url="$protocol://$host:$porta/http-bind" # Testar conexão if command -v curl &> /dev/null; then local response=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$url" 2>&1 || echo "000") if [[ "$response" == "200" ]] || [[ "$response" == "405" ]] || [[ "$response" == "000" ]]; then # 405 é esperado (Method Not Allowed para GET em /http-bind) print_success "Servidor acessível em $url" return 0 else print_warning "Servidor retornou status $response (pode ser normal para /http-bind)" return 0 fi elif command -v wget &> /dev/null; then if wget --spider --timeout=10 "$url" 2>&1 | grep -q "200 OK\|405\|connected"; then print_success "Servidor acessível em $url" return 0 else print_warning "Não foi possível verificar conectividade (wget)" return 1 fi else print_warning "curl ou wget não encontrado. Pulando teste de conectividade." return 1 fi } # Função para validar certificado SSL validar_certificado_ssl() { local dominio=$1 if [[ ! "$dominio" =~ ^localhost ]]; then print_info "Validando certificado SSL para $dominio..." local host=$(echo $dominio | cut -d: -f1) local porta=$(echo $dominio | cut -d: -f2) if [[ -z "$porta" ]]; then porta=443 fi if command -v openssl &> /dev/null; then local cert_info=$(echo | openssl s_client -connect "$host:$porta" -servername "$host" 2>&1 | grep -A 2 "Certificate chain\|Verify return code") if echo "$cert_info" | grep -q "Verify return code: 0"; then print_success "Certificado SSL válido" return 0 else print_warning "Certificado SSL não válido ou autoassinado" return 1 fi else print_warning "openssl não encontrado. Pulando validação de certificado." return 1 fi fi return 0 } # Função para gerar JWT Secret gerar_jwt_secret() { if command -v openssl &> /dev/null; then openssl rand -hex 32 elif [[ -r /dev/urandom ]]; then head -c 32 /dev/urandom | base64 | tr -d '\n' | head -c 64 else print_error "Não foi possível gerar JWT Secret. Instale openssl ou forneça manualmente." exit 1 fi } # Função para ler entrada do usuário ler_entrada() { local prompt=$1 local default=$2 local var_name=$3 if [[ "$NON_INTERACTIVE" == "true" ]]; then if [[ -n "$default" ]]; then eval "$var_name='$default'" return else print_error "Modo não-interativo requer valor para: $prompt" exit 1 fi fi local input if [[ -n "$default" ]]; then read -p "$(echo -e ${BLUE}$prompt${NC} [padrão: $default]): " input eval "$var_name=\${input:-$default}" else read -p "$(echo -e ${BLUE}$prompt${NC}): " input eval "$var_name='$input'" fi } # Função para exibir ajuda mostrar_ajuda() { cat << EOF Uso: $0 [OPÇÕES] Script de configuração interativa do Jitsi Meet para SGSE. OPÇÕES: --ambiente NOME Especificar ambiente (desenvolvimento, staging, producao) --domain DOMINIO Configurar domínio do servidor Jitsi --app-id ID Configurar App ID --jwt-secret SECRET Configurar JWT Secret (ou gerar automaticamente se não fornecido) --room-prefix PREFIXO Configurar prefixo de sala --use-https Usar HTTPS --accept-self-signed Aceitar certificados autoassinados --test-only Apenas testar configuração existente --validate-only Apenas validar sem salvar --non-interactive Modo não-interativo (para CI/CD) --help Mostrar esta ajuda EXEMPLOS: # Modo interativo $0 # Modo não-interativo $0 --domain meet.example.com --app-id sgse-app --use-https # Apenas validar $0 --validate-only --domain meet.example.com # Apenas testar $0 --test-only EOF } # Processar argumentos da linha de comando while [[ $# -gt 0 ]]; do case $1 in --ambiente) AMBIENTE="$2" shift 2 ;; --domain|--domínio) DOMAIN="$2" shift 2 ;; --app-id) APP_ID="$2" shift 2 ;; --jwt-secret) JWT_SECRET="$2" shift 2 ;; --room-prefix) ROOM_PREFIX="$2" shift 2 ;; --use-https) USE_HTTPS=true shift ;; --accept-self-signed) ACCEPT_SELF_SIGNED=true shift ;; --test-only) TEST_ONLY=true shift ;; --validate-only) VALIDATE_ONLY=true shift ;; --non-interactive) NON_INTERACTIVE=true shift ;; --help|-h) mostrar_ajuda exit 0 ;; *) print_error "Opção desconhecida: $1" mostrar_ajuda exit 1 ;; esac done # Banner echo -e "${BLUE}" cat << "EOF" ╔═══════════════════════════════════════════════════════════╗ ║ Configuração do Jitsi Meet para SGSE ║ ╚═══════════════════════════════════════════════════════════╝ EOF echo -e "${NC}" # Modo apenas teste if [[ "$TEST_ONLY" == "true" ]]; then print_info "Modo de teste apenas. Validando configuração existente..." # Aqui você pode adicionar lógica para testar configuração existente # Por exemplo, buscar do banco de dados ou arquivo de configuração exit 0 fi # Coletar informações if [[ "$NON_INTERACTIVE" != "true" ]]; then print_info "Coletando informações de configuração..." echo fi # Ambiente if [[ -z "$AMBIENTE" ]]; then ler_entrada "Ambiente (desenvolvimento, staging, producao)" "" AMBIENTE fi # Domínio while [[ -z "$DOMAIN" ]] || ! validar_dominio "$DOMAIN"; do if [[ -z "$DOMAIN" ]]; then ler_entrada "Domínio do servidor Jitsi (ex: localhost:8443 ou meet.example.com)" "" DOMAIN else print_error "Domínio inválido: $DOMAIN" DOMAIN="" ler_entrada "Domínio do servidor Jitsi" "" DOMAIN fi done # Detectar HTTPS automaticamente if [[ "$DOMAIN" =~ :8443$ ]] || [[ "$DOMAIN" =~ ^[^:]+$ ]] && [[ ! "$DOMAIN" =~ ^localhost ]]; then if [[ "$USE_HTTPS" != "true" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then read -p "$(echo -e ${BLUE}Usar HTTPS? (S/n)${NC}): " resposta if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then USE_HTTPS=true fi elif [[ -z "$USE_HTTPS" ]]; then USE_HTTPS=true fi fi # Aceitar certificados autoassinados if [[ "$USE_HTTPS" == "true" ]] && [[ "$DOMAIN" =~ localhost ]]; then if [[ "$ACCEPT_SELF_SIGNED" != "true" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then read -p "$(echo -e ${BLUE}Aceitar certificados autoassinados? (S/n)${NC}): " resposta if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then ACCEPT_SELF_SIGNED=true fi fi fi # App ID while [[ -z "$APP_ID" ]] || ! validar_app_id "$APP_ID"; do if [[ -z "$APP_ID" ]]; then ler_entrada "App ID" "sgse-app" APP_ID else print_error "App ID inválido: $APP_ID (deve conter apenas letras, números, hífens e underscores)" APP_ID="" ler_entrada "App ID" "sgse-app" APP_ID fi done # Room Prefix if [[ -z "$ROOM_PREFIX" ]]; then ler_entrada "Prefixo de sala" "sgse" ROOM_PREFIX fi # JWT Secret if [[ -z "$JWT_SECRET" ]]; then if [[ "$NON_INTERACTIVE" != "true" ]]; then read -p "$(echo -e ${BLUE}Gerar JWT Secret automaticamente? (S/n)${NC}): " resposta if [[ "$resposta" =~ ^[Ss]$ ]] || [[ -z "$resposta" ]]; then JWT_SECRET=$(gerar_jwt_secret) print_success "JWT Secret gerado: ${JWT_SECRET:0:16}..." else ler_entrada "JWT Secret (deixe vazio para desabilitar JWT)" "" JWT_SECRET fi else JWT_SECRET=$(gerar_jwt_secret) fi fi # Validar JWT Secret se fornecido if [[ -n "$JWT_SECRET" ]] && ! validar_jwt_secret "$JWT_SECRET"; then print_error "JWT Secret deve ter no mínimo 16 caracteres" exit 1 fi # JWT Audience (opcional) if [[ -z "$JWT_AUDIENCE" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then ler_entrada "JWT Audience (opcional, padrão: domínio)" "$DOMAIN" JWT_AUDIENCE fi # JWT Issuer (opcional) if [[ -z "$JWT_ISSUER" ]] && [[ "$NON_INTERACTIVE" != "true" ]]; then ler_entrada "JWT Issuer (opcional, padrão: App ID)" "$APP_ID" JWT_ISSUER fi # Validações print_info "Validando configuração..." # Validar domínio if ! validar_dominio "$DOMAIN"; then print_error "Domínio inválido: $DOMAIN" exit 1 fi # Validar App ID if ! validar_app_id "$APP_ID"; then print_error "App ID inválido: $APP_ID" exit 1 fi # Validar JWT Secret if [[ -n "$JWT_SECRET" ]] && ! validar_jwt_secret "$JWT_SECRET"; then print_error "JWT Secret inválido (mínimo 16 caracteres)" exit 1 fi print_success "Validações básicas passaram" # Testes de conectividade if [[ "$VALIDATE_ONLY" != "true" ]]; then print_info "Testando conectividade..." if testar_conectividade "$DOMAIN" "$USE_HTTPS"; then print_success "Conectividade OK" else print_warning "Não foi possível testar conectividade (servidor pode estar offline)" fi # Validar certificado SSL se HTTPS if [[ "$USE_HTTPS" == "true" ]]; then validar_certificado_ssl "$DOMAIN" fi fi # Resumo echo print_info "Resumo da configuração:" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo " Ambiente: ${AMBIENTE:-padrão}" echo " Domínio: $DOMAIN" echo " App ID: $APP_ID" echo " Prefixo de Sala: $ROOM_PREFIX" echo " HTTPS: $USE_HTTPS" echo " Cert. Autoassinado: $ACCEPT_SELF_SIGNED" if [[ -n "$JWT_SECRET" ]]; then echo " JWT Secret: ${JWT_SECRET:0:16}... (${#JWT_SECRET} caracteres)" else echo " JWT Secret: (não configurado)" fi if [[ -n "$JWT_AUDIENCE" ]]; then echo " JWT Audience: $JWT_AUDIENCE" fi if [[ -n "$JWT_ISSUER" ]]; then echo " JWT Issuer: $JWT_ISSUER" fi echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" # Se apenas validar, sair aqui if [[ "$VALIDATE_ONLY" == "true" ]]; then print_success "Validação concluída" exit 0 fi # Confirmar antes de salvar if [[ "$NON_INTERACTIVE" != "true" ]]; then echo read -p "$(echo -e ${BLUE}Salvar esta configuração? (S/n)${NC}): " confirmar if [[ ! "$confirmar" =~ ^[Ss]$ ]] && [[ -n "$confirmar" ]]; then print_info "Configuração cancelada pelo usuário" exit 0 fi fi # Gerar JSON de configuração CONFIG_JSON=$(cat < "$CONFIG_FILE" print_success "Configuração salva em: $CONFIG_FILE" # Instruções finais echo print_info "Próximos passos:" echo "1. Revise o arquivo de configuração: $CONFIG_FILE" echo "2. Acesse o painel SGSE: TI > Configurações do Jitsi" echo "3. Preencha os campos com os valores acima" echo "4. Teste a conexão usando o botão 'Testar Conexão'" echo "5. Salve a configuração no painel" if [[ -n "$JWT_SECRET" ]]; then echo print_warning "IMPORTANTE: Guarde o JWT Secret em local seguro!" print_warning "O JWT Secret não será exibido novamente." fi print_success "Configuração concluída!"