autenticarProcurador method

Future<TermoAutorizacaoResponse> autenticarProcurador({
  1. required String contratanteNome,
  2. required String autorNome,
  3. String? contribuinteNumero,
  4. String? certificadoPath,
  5. String? certificadoBase64,
  6. String? certificadoPassword,
  7. String? contratanteNumero,
  8. String? autorNumero,
})

Autentica procurador enviando XML assinado com Termo de Autorização

Parâmetros Obrigatórios

  • contratanteNome: Razão social da empresa contratante (quem faz requisições)
  • autorNome: Nome do procurador (quem assina o termo)

Parâmetros do Contribuinte (obrigatório se diferente do contratante)

  • contribuinteNumero: CPF/CNPJ do contribuinte (em nome de quem serão feitas as requisições)

Certificado de Assinatura (obrigatório se diferente do authenticate)

O certificado usado para assinar o termo pode ser diferente do usado na autenticação OAuth2.

Desktop/Mobile:

  • certificadoPath: Caminho do certificado PFX/PEM do procurador
  • certificadoPassword: Senha do certificado do procurador

Web (ou todas as plataformas):

  • certificadoBase64: Certificado PFX em Base64 (conteúdo do arquivo convertido)
  • certificadoPassword: Senha do certificado do procurador

Parâmetros Opcionais (obtidos do ApiClient)

  • contratanteNumero: CNPJ do contratante (padrão: do authenticate)
  • autorNumero: CPF/CNPJ do procurador (padrão: do authenticate)

Retorno

TermoAutorizacaoResponse contendo:

  • sucesso: se a autenticação foi bem-sucedida
  • autenticarProcuradorToken: token para usar em requisições subsequentes
  • dataExpiracao: quando o token expira
  • isCacheValido: se está usando resposta em cache

Erros Possíveis

Implementation

Future<TermoAutorizacaoResponse> autenticarProcurador({
  // Obrigatórios: nomes
  required String contratanteNome,
  required String autorNome,
  // Contribuinte: obrigatório se diferente do contratante
  String? contribuinteNumero,
  // Certificado de assinatura: pode ser diferente do OAuth2
  String? certificadoPath,
  String? certificadoBase64,
  String? certificadoPassword,
  // Opcionais: obtidos do ApiClient se não fornecidos
  String? contratanteNumero,
  String? autorNumero,
}) async {
  try {
    // Verificar se ApiClient está autenticado
    if (!_apiClient.isAutenticado) {
      throw ExcecaoAutenticaProcurador(
        'ApiClient não está autenticado. Chame authenticate() primeiro.',
        codigo: 'NAO_AUTENTICADO',
        statusHttp: 401,
      );
    }

    // Obter dados do ApiClient (se não fornecidos)
    final finalContratanteNumero =
        contratanteNumero ?? _apiClient.contratanteNumero!;
    final finalAutorNumero =
        autorNumero ?? _apiClient.autorPedidoDadosNumero!;
    final finalContribuinteNumero =
        contribuinteNumero ?? finalContratanteNumero;

    // Certificado de assinatura: pode ser diferente do OAuth2
    // Prioridade: certificadoBase64 > certificadoPath > certificado do authenticate
    String? finalCertificadoPath;
    String? finalCertificadoBase64;
    String? finalCertificadoPassword;

    if (certificadoBase64 != null && certificadoBase64.isNotEmpty) {
      // Usar Base64 fornecido (funciona em todas as plataformas)
      finalCertificadoBase64 = certificadoBase64;
      finalCertificadoPassword = certificadoPassword;
    } else if (certificadoPath != null && certificadoPath.isNotEmpty) {
      // Usar path fornecido (Desktop/Mobile)
      finalCertificadoPath = certificadoPath;
      finalCertificadoPassword = certificadoPassword;
    } else if (_apiClient.certificadoPath != null) {
      // Usar certificado do authenticate
      finalCertificadoPath = _apiClient.certificadoPath;
      finalCertificadoPassword = _apiClient.certificadoSenha;
    } else {
      throw ExcecaoAssinaturaCertificado(
        'Nenhum certificado fornecido para assinatura.\n'
        'Forneça certificadoPath (Desktop/Mobile) ou certificadoBase64 (Web/todas).',
      );
    }

    if (finalCertificadoPassword == null ||
        finalCertificadoPassword.isEmpty) {
      throw ExcecaoAssinaturaCertificado(
        'Senha do certificado não fornecida.',
      );
    }

    // 1. Criar termo de autorização
    final termo = TermoAutorizacaoRequest.comDataAtual(
      contratanteNumero: finalContratanteNumero,
      contratanteNome: contratanteNome,
      autorPedidoDadosNumero: finalAutorNumero,
      autorPedidoDadosNome: autorNome,
      certificadoPath: finalCertificadoPath,
      certificadoPassword: finalCertificadoPassword,
    );

    // 2. Validar dados (transparente)
    final errosValidacao = termo.validarDados();
    if (errosValidacao.isNotEmpty) {
      throw ExcecaoAutenticaProcurador(
        'Dados do termo de autorização inválidos:\n${errosValidacao.join('\n')}',
        codigo: 'DADOS_INVALIDOS',
        statusHttp: 400,
      );
    }

    // 3. Criar XML do termo
    final xml = termo.criarXmlTermo();

    // 4. Assinar digitalmente com certificado real
    final xmlAssinado = await _assinarXmlReal(
      xml,
      certificadoPath: finalCertificadoPath,
      certificadoBase64: finalCertificadoBase64,
      certificadoPassword: finalCertificadoPassword,
    );

    // 5. Enviar para API e obter token
    return await _enviarParaAPI(
      xmlAssinado,
      finalContratanteNumero,
      finalAutorNumero,
      finalContribuinteNumero,
    );
  } on ExcecaoAutenticaProcurador {
    rethrow;
  } catch (e) {
    throw ExcecaoAutenticaProcurador(
      'Erro na autenticação de procurador: $e',
      codigo: 'ERRO_INESPERADO',
      statusHttp: 500,
    );
  }
}