Files
chatc2/deploy-linux/patch_node_firebird.py
AyronSantos ae629d1dc2 Migração para PostgreSQL multi-driver + correções de segurança
- Camada de banco unificada (src/database.js): drivers Postgres/Firebird,
  tradutor de SQL, suporte a schema e pool de conexões
- Conexões: novo_local (Postgres externo) e firebird_local (legado)
- Tela de rotas da API redesenhada (auth, params, exemplos de body)
- Correções de segurança (críticos/altos/médios/baixos): XSS no chat,
  escalonamento de privilégio, mídia autenticada, SQL restrito a gerente,
  JWT sem fallback + issuer, IDOR em conversas, CORS por allowlist,
  rate-limit no login, limites de corpo por rota
- Deploy alinhado: install.sh grava .env com PG_*, migracoes.js driver-aware

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:02:59 -03:00

128 lines
4.8 KiB
Python

#!/usr/bin/env python3
"""
patch_node_firebird.py - Aplica patches de compatibilidade node-firebird
Patches aplicados:
1. SRP empty buffer (Firebird 3.0 Legacy_Auth)
2. Correcao de sintaxe para Node.js v22+ (colchete faltante)
Uso: python3 patch_node_firebird.py <caminho_do_projeto>
Ex: python3 patch_node_firebird.py /home/chatc2/chatc2
"""
import sys
import os
def patch_srp(project_dir):
"""Patch 1: compatibilidade SRP com Firebird 3.0 Legacy_Auth"""
filepath = os.path.join(project_dir, 'node_modules',
'node-firebird', 'lib', 'wire', 'connection.js')
if not os.path.isfile(filepath):
print(" [ERRO] Arquivo connection.js nao encontrado")
return False
with open(filepath, 'r') as f:
content = f.read()
if "No auth data from server" in content:
print(" [OK] Patch 1 (SRP) ja aplicado")
return True
old = (
' // TODO : Fallback Srp256 to Srp ?\n'
' /*if (!d.buffer) {\n'
' cnx.sendOpContAuth(\n'
' cnx.clientKeys.public.toString(16),\n'
' DEFAULT_ENCODING,\n'
' accept.pluginName\n'
' );\n'
'\n'
' return cb(new Error(\'login\'));\n'
' }*/\n'
'\n'
' // Check buffer contains salt\n'
' var saltLen = d.buffer.readUInt16LE(0);'
)
new = (
' // No auth data from server - server accepted the connection\n'
' // without requiring SRP. This happens with Firebird 3.0 when\n'
' // the server already validated the client.\n'
' if (!d || !d.buffer) {\n'
" accept.authData = '';\n"
" accept.sessionKey = '';\n"
' } else {\n'
' // Check buffer contains salt\n'
' var saltLen = d.buffer.readUInt16LE(0);'
)
if old in content:
content = content.replace(old, new, 1)
with open(filepath, 'w') as f:
f.write(content)
print(" [OK] Patch 1 (SRP) aplicado")
return True
else:
print(" [AVISO] Patch 1 (SRP) nao encontrado - codigo ja modificado")
return True # nao e erro
def patch_syntax(project_dir):
"""Patch 2: colchete faltante (Node.js v22 nao tolera essa sintaxe)"""
filepath = os.path.join(project_dir, 'node_modules',
'node-firebird', 'lib', 'wire', 'connection.js')
if not os.path.isfile(filepath):
return False
with open(filepath, 'r') as f:
content = f.read()
# Verifica se ja foi corrigido
if "fecha o else do if" in content:
print(" [OK] Patch 2 (sintaxe) ja aplicado")
return True
# O erro: else block do if(!d||!d.buffer) nao tem chave de fechamento
# Linha original termina com: accept.sessionKey = proof.clientSessionKey;
# Linha seguinte: } else if (accept.pluginName === Const.AUTH_PLUGIN_LEGACY)
# Precisa de um } extra entre elas para fechar o else block
old = (
' accept.authData = proof.authData.toString(16);\n'
' accept.sessionKey = proof.clientSessionKey;\n'
' } else if (accept.pluginName === Const.AUTH_PLUGIN_LEGACY) {'
)
new = (
' accept.authData = proof.authData.toString(16);\n'
' accept.sessionKey = proof.clientSessionKey;\n'
' } // fecha o else do if (!d || !d.buffer)\n'
' } else if (accept.pluginName === Const.AUTH_PLUGIN_LEGACY) {'
)
if old in content:
content = content.replace(old, new, 1)
with open(filepath, 'w') as f:
f.write(content)
print(" [OK] Patch 2 (sintaxe Node22) aplicado")
return True
else:
print(" [AVISO] Patch 2 (sintaxe) - padrao nao encontrado")
return True
if __name__ == '__main__':
if len(sys.argv) < 2:
print("Uso: python3 patch_node_firebird.py <caminho_do_projeto>")
sys.exit(1)
project_dir = sys.argv[1]
print(f" Aplicando patches em: {project_dir}")
r1 = patch_srp(project_dir)
r2 = patch_syntax(project_dir)
if r1 and r2:
print(" Patches aplicados com sucesso")
sys.exit(0)
else:
print(" Alguns patches falharam")
sys.exit(1)