Sincronicidade do JavaScript: combinando ouvinte onAuthRequired e massagem nativa

eu tenho istoproblema ... e eu tenho tentado passar um par de nome de usuário e senha para background.js da minha extensão. O processo é o seguinte:

Um servidor de credenciais (CS) é iniciado com tokens de credenciais criptografadosSelenium abre o navegador com extensão personalizadaA extensão é acionada onAuthRequiredO host de mensagens nativas (NMH) é iniciado e recebe uma mensagem 'pronta'O NMH usa um protocolo simples para solicitar tokens do CSO NMH descriptografa os tokensO NMH passa as credenciais para background.jsbackground.js retorna as credenciais para o chromeA mágica da autenticação acontece no servidor remoto

Resolvi tudo até 6 ... talvez 7. O problema é que não consigo realmente capturar o que o NMH está enviando. Parece que as credenciais não estão formatadas corretamente; portanto, elas estão sendo rejeitadas ou há um problema com a forma como o lado do JavaScript é organizado e, portanto, é apenas um caso de código quebrado. Também é possível que o que pretendo não seja de todo possível ... embora eu duvide que seja esse o caso.

Fornecerei o máximo de código possível ... e, embora aprecie qualquer ajuda, fico feliz em obter um exemplo genérico que pode ser modificado no meu próprio tempo.

Tem uma abordagem melhor? Sou todo ouvidos! É um prazer criar uma nova pergunta para abordar outras idéias.

EDIÇÃO 1.0: Devo acrescentar que, quando executado, o alerta na linha 9 aparece. Quando modificado para ler:

window.alert(String(response));

eu recebo[object Object]

EDIT 2.0: eu mudeiwindow.alert(String(response)); parawindow.alert(JSON.stringify(response)); e produziu o resultado esperado:{"username":"\"some_user\"","password":"\"1Password\"} Espero que isso se traduza em '{username: "some_user", senha: "1Password"}'

Parece haver um problema ao passar o valor da resposta aos creds, já que o NMH falha na execução quando tento acessar a propriedade nome de usuário / senha dos creds fora do retorno de chamada. Provavelmente esse é um problema de escopo ...

Edit 3.0: Encontrei o problema - é um problema de sincronicidade. Eu encontrei muitas, muitas perguntas sobre isso - eu responderei quando criar um trabalho em torno de mim. Sinta-se à vontade para responder com uma solução, caso você tenha uma.

Atualbackground.js (não está funcionando)

chrome.webRequest.onAuthRequired.addListener(() => {
 var hostName = "aardvark_nm_host";
 var creds = null;

 chrome.runtime.sendNativeMessage(
   hostName,
   { text: "Ready" },
   function(response){
     window.alert("response");
     console.log(response);
     creds = JSON.parse(response);
   }
 );
 return {authCredentials: creds};
},
 {urls: ["<all_urls>"]},
 ['blocking']
);

Atual aardvark_nm_host.py (provavelmente funcionando)

#!/usr/bin/env python

from locksmith import decrypt_token, KEYFILE
import socket
import struct
import sys
import json

PORT = 9999
ADDR = 'localhost'

ERRMSG = {"username":"ERROR", "password":"password"}

def report_string(string):
  def transceive(signal):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server = (ADDR, PORT)
    sock.connect(server)

    try:
      sock.sendall(signal)
    except Exception as e:
      print >>sys.stderr, e
      sock.close()
    try:
      sock.sendall(string)
      sock.close()
    except Exception as e:
      print >>sys.stderr, e
      sock.close()

  transceive('S')

def get_tokens():
  def recv_burst(sock):
    total_data = []
    while True:
      data = sock.recv(1024)
      if not data:
        break
      total_data.append(data)
    return ''.join(total_data)

  def transceive(signal):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server = (ADDR, PORT)
    sock.connect(server)

    try:
      sock.sendall(signal)
      message = recv_burst(sock)

    except Exception as e:
      report_string(e)

    finally:
      sock.close()
      
    return message

  try:
    username = transceive('U')
    username = decrypt_token(username)
    report_string(username)
  except Exception as e:
    report_string(str(e))
    username = "TOKEN_ERROR"
  try:
    password = transceive('P')
    password = decrypt_token(password)
    report_string(password)
  except Exception as e:
    report_string(str(e))
    password = "TOKEN_ERROR"

  return {"username":username, "password":password}

def read_message():
  text_length = sys.stdin.read(4)
  if len(text_length) == 0:
    sys.exit(0)

  text_length = struct.unpack('@I', text_length)[0]
  text = sys.stdin.read(text_length)
  return json.loads(text)
  
def encode_message(message):
  encoded_content = json.dumps(message)
  encoded_length = struct.pack('@I', len(encoded_content))
  return {'length': encoded_length, 'content': encoded_content}
  
def send_message(encoded_message):
  sys.stdout.write(encoded_message['length'])
  sys.stdout.write(encoded_message['content'])
  sys.stdout.flush()

def interpretation(message):
  return message["text"] == "Ready"

while True:
  received_message = read_message()
  report_string(received_message)

  if interpretation(received_message):
    creds = get_tokens()
    send_message(encode_message(creds))
    creds = None
  else:
    send_message(encode_message(ERRMSG))

Extensão atual manifest.json

{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "authvark",
    "permissions": [
        "<all_urls>",
        "webRequest",
        "webRequestBlocking",
        "nativeMessaging"
    ],
    "background": {
        "scripts": ["background.js"],
        "persistent": false
    }
}

hosts de mensagens nativas / manifest.json

{
  "name": "aardvark_nm_host",
  "description": "Intermediary Credential Host",
  "path": "/path/to/aardvark_nm_host.py",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://.../"
  ]
}

questionAnswers(1)

yourAnswerToTheQuestion