Fix crash when logging in after a forced logout
Also tidy up bridge notices during the login flow
This commit is contained in:
parent
3286d7e6e2
commit
c5eea7b50b
|
@ -55,6 +55,11 @@ async def login_do(evt: CommandEvent, gen: AsyncGenerator[Tuple[str, str], None]
|
||||||
failure = False
|
failure = False
|
||||||
async for item in gen:
|
async for item in gen:
|
||||||
if item[0] == "qr":
|
if item[0] == "qr":
|
||||||
|
message = "Open LINE on your primary device and scan this QR code:"
|
||||||
|
content = TextMessageEventContent(body=message, msgtype=MessageType.NOTICE)
|
||||||
|
content.set_reply(evt.event_id)
|
||||||
|
await evt.az.intent.send_message(evt.room_id, content)
|
||||||
|
|
||||||
url = item[1]
|
url = item[1]
|
||||||
buffer = io.BytesIO()
|
buffer = io.BytesIO()
|
||||||
image = qrcode.make(url)
|
image = qrcode.make(url)
|
||||||
|
@ -69,7 +74,6 @@ async def login_do(evt: CommandEvent, gen: AsyncGenerator[Tuple[str, str], None]
|
||||||
content.set_edit(qr_event_id)
|
content.set_edit(qr_event_id)
|
||||||
await evt.az.intent.send_message(evt.room_id, content)
|
await evt.az.intent.send_message(evt.room_id, content)
|
||||||
else:
|
else:
|
||||||
content.set_reply(evt.event_id)
|
|
||||||
qr_event_id = await evt.az.intent.send_message(evt.room_id, content)
|
qr_event_id = await evt.az.intent.send_message(evt.room_id, content)
|
||||||
elif item[0] == "pin":
|
elif item[0] == "pin":
|
||||||
pin = item[1]
|
pin = item[1]
|
||||||
|
@ -79,9 +83,10 @@ async def login_do(evt: CommandEvent, gen: AsyncGenerator[Tuple[str, str], None]
|
||||||
content.set_edit(pin_event_id)
|
content.set_edit(pin_event_id)
|
||||||
await evt.az.intent.send_message(evt.room_id, content)
|
await evt.az.intent.send_message(evt.room_id, content)
|
||||||
else:
|
else:
|
||||||
content.set_reply(evt.event_id)
|
|
||||||
pin_event_id = await evt.az.intent.send_message(evt.room_id, content)
|
pin_event_id = await evt.az.intent.send_message(evt.room_id, content)
|
||||||
elif item[0] in ("failure", "error"):
|
elif item[0] == "login_success":
|
||||||
|
await evt.reply("Successfully logged in, waiting for LINE to load...")
|
||||||
|
elif item[0] in ("login_failure", "error"):
|
||||||
# TODO Handle errors differently?
|
# TODO Handle errors differently?
|
||||||
failure = True
|
failure = True
|
||||||
reason = item[1]
|
reason = item[1]
|
||||||
|
@ -91,7 +96,7 @@ async def login_do(evt: CommandEvent, gen: AsyncGenerator[Tuple[str, str], None]
|
||||||
# else: pass
|
# else: pass
|
||||||
|
|
||||||
if not failure and evt.sender.command_status:
|
if not failure and evt.sender.command_status:
|
||||||
await evt.reply("Successfully logged in")
|
await evt.reply("LINE loading complete")
|
||||||
await evt.sender.sync()
|
await evt.sender.sync()
|
||||||
# else command was cancelled or failed. Don't post message about it, "cancel" command or failure did already
|
# else command was cancelled or failed. Don't post message about it, "cancel" command or failure did already
|
||||||
evt.sender.command_status = None
|
evt.sender.command_status = None
|
||||||
|
|
|
@ -119,8 +119,12 @@ class Client(RPCClient):
|
||||||
data.append(("pin", req["pin"]))
|
data.append(("pin", req["pin"]))
|
||||||
event.set()
|
event.set()
|
||||||
|
|
||||||
|
async def success_handler(req: LoginCommand) -> None:
|
||||||
|
data.append(("login_success", None))
|
||||||
|
event.set()
|
||||||
|
|
||||||
async def failure_handler(req: LoginCommand) -> None:
|
async def failure_handler(req: LoginCommand) -> None:
|
||||||
data.append(("failure", req.get("reason")))
|
data.append(("login_failure", req.get("reason")))
|
||||||
event.set()
|
event.set()
|
||||||
|
|
||||||
async def cancel_watcher() -> None:
|
async def cancel_watcher() -> None:
|
||||||
|
@ -145,7 +149,8 @@ class Client(RPCClient):
|
||||||
|
|
||||||
self.add_event_handler("qr", qr_handler)
|
self.add_event_handler("qr", qr_handler)
|
||||||
self.add_event_handler("pin", pin_handler)
|
self.add_event_handler("pin", pin_handler)
|
||||||
self.add_event_handler("failure", failure_handler)
|
self.add_event_handler("login_success", success_handler)
|
||||||
|
self.add_event_handler("login_failure", failure_handler)
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
await event.wait()
|
await event.wait()
|
||||||
|
@ -158,4 +163,5 @@ class Client(RPCClient):
|
||||||
finally:
|
finally:
|
||||||
self.remove_event_handler("qr", qr_handler)
|
self.remove_event_handler("qr", qr_handler)
|
||||||
self.remove_event_handler("pin", pin_handler)
|
self.remove_event_handler("pin", pin_handler)
|
||||||
self.remove_event_handler("failure", failure_handler)
|
self.remove_event_handler("login_success", success_handler)
|
||||||
|
self.remove_event_handler("login_failure", failure_handler)
|
||||||
|
|
|
@ -177,7 +177,7 @@ class User(DBUser, BaseUser):
|
||||||
await portal.handle_remote_receipt(receipt)
|
await portal.handle_remote_receipt(receipt)
|
||||||
|
|
||||||
async def handle_logged_out(self) -> None:
|
async def handle_logged_out(self) -> None:
|
||||||
await self.send_bridge_notice("Logged out of LINE. Please run the \"login\" command to log back in.")
|
await self.send_bridge_notice("Logged out of LINE. Please run either \"login-qr\" or \"login-email\" to log back in.")
|
||||||
if self._connection_check_task:
|
if self._connection_check_task:
|
||||||
self._connection_check_task.cancel()
|
self._connection_check_task.cancel()
|
||||||
self._connection_check_task = None
|
self._connection_check_task = None
|
||||||
|
|
|
@ -135,11 +135,19 @@ export default class Client {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFailure(reason) {
|
sendLoginSuccess() {
|
||||||
this.log(`Sending failure to client${reason ? `: "${reason}"` : ""}`)
|
this.log("Sending login success to client")
|
||||||
return this._write({
|
return this._write({
|
||||||
id: --this.notificationID,
|
id: --this.notificationID,
|
||||||
command: "failure",
|
command: "login_success",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sendLoginFailure(reason) {
|
||||||
|
this.log(`Sending login failure to client${reason ? `: "${reason}"` : ""}`)
|
||||||
|
return this._write({
|
||||||
|
id: --this.notificationID,
|
||||||
|
command: "login_failure",
|
||||||
reason,
|
reason,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ export default class MessagesPuppeteer {
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await Promise.race([
|
const result = await Promise.race([
|
||||||
() => this.page.waitForSelector("#wrap_message_sync", {timeout: 2000})
|
() => this.page.waitForSelector("#mainApp:not(.MdNonDisp)", {timeout: 2000})
|
||||||
.then(value => {
|
.then(value => {
|
||||||
loginSuccess = true
|
loginSuccess = true
|
||||||
return value
|
return value
|
||||||
|
@ -227,11 +227,13 @@ export default class MessagesPuppeteer {
|
||||||
delete this.login_email
|
delete this.login_email
|
||||||
delete this.login_password
|
delete this.login_password
|
||||||
|
|
||||||
if (!loginSuccess) {
|
const messageSyncElement = loginSuccess ? await this.page.waitForSelector("#wrap_message_sync") : null
|
||||||
|
if (!loginSuccess || !messageSyncElement) {
|
||||||
this._sendLoginFailure(result)
|
this._sendLoginFailure(result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._sendLoginSuccess()
|
||||||
this.log("Waiting for sync")
|
this.log("Waiting for sync")
|
||||||
try {
|
try {
|
||||||
await this.page.waitForFunction(
|
await this.page.waitForFunction(
|
||||||
|
@ -242,14 +244,12 @@ export default class MessagesPuppeteer {
|
||||||
// TODO Sometimes it gets stuck at 99%...??
|
// TODO Sometimes it gets stuck at 99%...??
|
||||||
},
|
},
|
||||||
{timeout: 10000}, // Assume 10 seconds is long enough
|
{timeout: 10000}, // Assume 10 seconds is long enough
|
||||||
result)
|
messageSyncElement)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
//this._sendLoginFailure(`Failed to sync: ${err}`)
|
//this._sendLoginFailure(`Failed to sync: ${err}`)
|
||||||
this.log("LINE's sync took too long, assume it's fine and carry on...")
|
this.log("LINE's sync took too long, assume it's fine and carry on...")
|
||||||
} finally {
|
} finally {
|
||||||
const syncText = await this.page.evaluate(
|
const syncText = await messageSyncElement.evaluate(e => e.innerText)
|
||||||
messageSyncElement => messageSyncElement.innerText,
|
|
||||||
result)
|
|
||||||
this.log(`Final sync text is: "${syncText}"`)
|
this.log(`Final sync text is: "${syncText}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,14 +758,24 @@ export default class MessagesPuppeteer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sendLoginSuccess() {
|
||||||
|
this.error("Login success")
|
||||||
|
if (this.client) {
|
||||||
|
this.client.sendLoginSuccess().catch(err =>
|
||||||
|
this.error("Failed to send login success to client:", err))
|
||||||
|
} else {
|
||||||
|
this.log("No client connected, not sending login success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_sendLoginFailure(reason) {
|
_sendLoginFailure(reason) {
|
||||||
this.loginRunning = false
|
this.loginRunning = false
|
||||||
this.error(`Login failure: ${reason ? reason : "cancelled"}`)
|
this.error(`Login failure: ${reason ? reason : "cancelled"}`)
|
||||||
if (this.client) {
|
if (this.client) {
|
||||||
this.client.sendFailure(reason).catch(err =>
|
this.client.sendLoginFailure(reason).catch(err =>
|
||||||
this.error("Failed to send failure reason to client:", err))
|
this.error("Failed to send login failure to client:", err))
|
||||||
} else {
|
} else {
|
||||||
this.log("No client connected, not sending failure reason")
|
this.log("No client connected, not sending login failure")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue