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 remotoResolvi 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://.../"
]
}