Compare commits
No commits in common. "8c2775056d97eccb43ad8777c1b74dda1dfadf26" and "db41292be7a98117d0cc44ab3a1260d757e1a166" have entirely different histories.
8c2775056d
...
db41292be7
@ -24,7 +24,7 @@ from mautrix.util.signed_token import sign_token
|
|||||||
from ..kt.client import Client as KakaoTalkClient
|
from ..kt.client import Client as KakaoTalkClient
|
||||||
from ..kt.client.errors import DeviceVerificationRequired, IncorrectPasscode, IncorrectPassword, CommandException
|
from ..kt.client.errors import DeviceVerificationRequired, IncorrectPasscode, IncorrectPassword, CommandException
|
||||||
|
|
||||||
from .. import puppet as pu
|
#from .. import puppet as pu
|
||||||
from .typehint import CommandEvent
|
from .typehint import CommandEvent
|
||||||
|
|
||||||
SECTION_AUTH = HelpSection("Authentication", 10, "")
|
SECTION_AUTH = HelpSection("Authentication", 10, "")
|
||||||
@ -53,7 +53,7 @@ try_again_or_cancel = "Try again, or say `$cmdprefix+sp cancel` to give up."
|
|||||||
help_args="[_email_]",
|
help_args="[_email_]",
|
||||||
)
|
)
|
||||||
async def login(evt: CommandEvent) -> None:
|
async def login(evt: CommandEvent) -> None:
|
||||||
if await evt.sender.is_logged_in():
|
if evt.sender.client:
|
||||||
await evt.reply("You're already logged in")
|
await evt.reply("You're already logged in")
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -156,43 +156,10 @@ async def _handle_login_failure(evt: CommandEvent, e: Exception) -> None:
|
|||||||
await evt.reply(f"{message}: {e}")
|
await evt.reply(f"{message}: {e}")
|
||||||
|
|
||||||
|
|
||||||
@command_handler(
|
@command_handler(needs_auth=True, help_section=SECTION_AUTH, help_text="Log out of KakaoTalk")
|
||||||
needs_auth=True,
|
|
||||||
help_section=SECTION_AUTH,
|
|
||||||
help_text="Log out of KakaoTalk (and optionally change your virtual device ID for next login)",
|
|
||||||
help_args="[--reset-device]",
|
|
||||||
)
|
|
||||||
async def logout(evt: CommandEvent) -> None:
|
async def logout(evt: CommandEvent) -> None:
|
||||||
if len(evt.args) >= 1:
|
#puppet = await pu.Puppet.get_by_ktid(evt.sender.ktid)
|
||||||
if evt.args[0] == "--reset-device":
|
await evt.sender.logout()
|
||||||
reset_device = True
|
#if puppet.is_real_user:
|
||||||
else:
|
# await puppet.switch_mxid(None, None)
|
||||||
await evt.reply("**Usage:** `$cmdprefix+sp logout [--reset-device]`")
|
await evt.reply("Successfully logged out")
|
||||||
return
|
|
||||||
else:
|
|
||||||
reset_device = False
|
|
||||||
|
|
||||||
puppet = await pu.Puppet.get_by_ktid(evt.sender.ktid)
|
|
||||||
await evt.sender.logout(reset_device=reset_device)
|
|
||||||
if puppet.is_real_user:
|
|
||||||
await puppet.switch_mxid(None, None)
|
|
||||||
|
|
||||||
message = "Successfully logged out"
|
|
||||||
if reset_device:
|
|
||||||
message += (
|
|
||||||
", and your next login will use a different device ID.\n\n"
|
|
||||||
"The old device must be manually de-registered from the KakaoTalk app."
|
|
||||||
)
|
|
||||||
await evt.reply(message)
|
|
||||||
|
|
||||||
|
|
||||||
@command_handler(needs_auth=False, help_section=SECTION_AUTH, help_text="Change your virtual device ID for next login")
|
|
||||||
async def reset_device(evt: CommandEvent) -> None:
|
|
||||||
if await evt.sender.is_logged_in():
|
|
||||||
await evt.reply("This command requires you to be logged out.")
|
|
||||||
else:
|
|
||||||
await evt.sender.logout(reset_device=True)
|
|
||||||
await evt.reply(
|
|
||||||
"Your next login will use a different device ID.\n\n"
|
|
||||||
"The old device must be manually de-registered from the KakaoTalk app."
|
|
||||||
)
|
|
||||||
|
@ -172,7 +172,7 @@ class User(DBUser, BaseUser):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def has_state(self) -> bool:
|
def has_state(self) -> bool:
|
||||||
return bool(self.uuid and self.ktid and self.access_token and self.refresh_token)
|
return self.uuid and self.ktid and self.access_token and self.refresh_token
|
||||||
|
|
||||||
# region Database getters
|
# region Database getters
|
||||||
|
|
||||||
@ -233,13 +233,10 @@ class User(DBUser, BaseUser):
|
|||||||
|
|
||||||
async def get_uuid(self, force: bool = False) -> str:
|
async def get_uuid(self, force: bool = False) -> str:
|
||||||
if self.uuid is None or force:
|
if self.uuid is None or force:
|
||||||
self.uuid = await self._generate_uuid()
|
self.uuid = await Client.generate_uuid(await self.get_all_uuids())
|
||||||
await self.save()
|
await self.save()
|
||||||
return self.uuid
|
return self.uuid
|
||||||
|
|
||||||
async def _generate_uuid(self) -> str:
|
|
||||||
return await Client.generate_uuid(await self.get_all_uuids())
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -372,7 +369,8 @@ class User(DBUser, BaseUser):
|
|||||||
finally:
|
finally:
|
||||||
self._is_refreshing = False
|
self._is_refreshing = False
|
||||||
|
|
||||||
async def logout(self, *, remove_ktid: bool = True, reset_device: bool = False) -> bool:
|
async def logout(self, remove_ktid: bool = True) -> bool:
|
||||||
|
# TODO Remove tokens too?
|
||||||
ok = True
|
ok = True
|
||||||
self.stop_listen()
|
self.stop_listen()
|
||||||
if self.has_state:
|
if self.has_state:
|
||||||
@ -387,15 +385,12 @@ class User(DBUser, BaseUser):
|
|||||||
await self.client.stop()
|
await self.client.stop()
|
||||||
self.client = None
|
self.client = None
|
||||||
|
|
||||||
if self.ktid and remove_ktid:
|
if remove_ktid:
|
||||||
|
if self.ktid:
|
||||||
#await UserPortal.delete_all(self.ktid)
|
#await UserPortal.delete_all(self.ktid)
|
||||||
del self.by_ktid[self.ktid]
|
del self.by_ktid[self.ktid]
|
||||||
self.ktid = None
|
self.ktid = None
|
||||||
|
self.uuid = None
|
||||||
if reset_device:
|
|
||||||
self.uuid = await self._generate_uuid()
|
|
||||||
self.access_token = None
|
|
||||||
self.refresh_token = None
|
|
||||||
|
|
||||||
await self.save()
|
await self.save()
|
||||||
return ok
|
return ok
|
||||||
@ -588,11 +583,10 @@ class User(DBUser, BaseUser):
|
|||||||
self.log.info("TODO: stop_listen")
|
self.log.info("TODO: stop_listen")
|
||||||
|
|
||||||
async def on_logged_in(self, oauth_credential: OAuthCredential) -> None:
|
async def on_logged_in(self, oauth_credential: OAuthCredential) -> None:
|
||||||
self.log.debug(f"Successfully logged in as {oauth_credential.userId}")
|
self.log.debug(f"Successfully logged in as {oauth_credential.uuid}")
|
||||||
self.oauth_credential = oauth_credential
|
self.oauth_credential = oauth_credential
|
||||||
self.client = Client(self, log=self.log.getChild("ktclient"))
|
self.client = Client(self, log=self.log.getChild("ktclient"))
|
||||||
await self.save()
|
await self.save()
|
||||||
self._is_logged_in = True
|
|
||||||
try:
|
try:
|
||||||
self._logged_in_info = await self.client.fetch_logged_in_user(post_login=True)
|
self._logged_in_info = await self.client.fetch_logged_in_user(post_login=True)
|
||||||
self._logged_in_info_time = time.monotonic()
|
self._logged_in_info_time = time.monotonic()
|
||||||
|
@ -28,7 +28,6 @@ import {
|
|||||||
|
|
||||||
|
|
||||||
class UserClient {
|
class UserClient {
|
||||||
static #initializing = false
|
|
||||||
|
|
||||||
#talkClient = new TalkClient()
|
#talkClient = new TalkClient()
|
||||||
get talkClient() { return this.#talkClient }
|
get talkClient() { return this.#talkClient }
|
||||||
@ -38,28 +37,16 @@ class UserClient {
|
|||||||
get serviceClient() { return this.#serviceClient }
|
get serviceClient() { return this.#serviceClient }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DO NOT CONSTRUCT DIRECTLY. Callers should use {@link UserClient#create} instead.
|
* @param {string} mxid The ID of the associated Matrix user
|
||||||
* @param {string} mxid
|
* @param {OAuthCredential} credential The tokens that API calls may use
|
||||||
* @param {OAuthCredential} credential
|
|
||||||
*/
|
*/
|
||||||
constructor(mxid, credential) {
|
constructor(mxid, credential) {
|
||||||
if (!UserClient.#initializing) {
|
|
||||||
throw new Error("Private constructor")
|
|
||||||
}
|
|
||||||
UserClient.#initializing = false
|
|
||||||
|
|
||||||
this.mxid = mxid
|
this.mxid = mxid
|
||||||
this.credential = credential
|
this.credential = credential
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} mxid The ID of the associated Matrix user
|
|
||||||
* @param {OAuthCredential} credential The tokens that API calls may use
|
|
||||||
*/
|
|
||||||
static async create(mxid, credential) {
|
static async create(mxid, credential) {
|
||||||
this.#initializing = true
|
|
||||||
const userClient = new UserClient(mxid, credential)
|
const userClient = new UserClient(mxid, credential)
|
||||||
|
|
||||||
userClient.#serviceClient = await ServiceApiClient.create(this.credential)
|
userClient.#serviceClient = await ServiceApiClient.create(this.credential)
|
||||||
return userClient
|
return userClient
|
||||||
}
|
}
|
||||||
@ -207,9 +194,9 @@ export default class PeerClient {
|
|||||||
/**
|
/**
|
||||||
* Checked lookup of a UserClient for a given mxid.
|
* Checked lookup of a UserClient for a given mxid.
|
||||||
* @param {string} mxid
|
* @param {string} mxid
|
||||||
* @returns {UserClient}
|
|
||||||
*/
|
*/
|
||||||
#getUser(mxid) {
|
#getUser(mxid) {
|
||||||
|
/** @type {UserClient} */
|
||||||
const userClient = this.userClients.get(mxid)
|
const userClient = this.userClients.get(mxid)
|
||||||
if (userClient === undefined) {
|
if (userClient === undefined) {
|
||||||
throw new Error(`Could not find user ${mxid}`)
|
throw new Error(`Could not find user ${mxid}`)
|
||||||
@ -217,17 +204,6 @@ export default class PeerClient {
|
|||||||
return userClient
|
return userClient
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the service client for the specified user ID, or create
|
|
||||||
* and return a new service client if no user ID is provided.
|
|
||||||
* @param {string} mxid
|
|
||||||
* @param {OAuthCredential} oauth_credential
|
|
||||||
*/
|
|
||||||
async #getServiceClient(mxid, oauth_credential) {
|
|
||||||
return this.userClients.get(mxid)?.serviceClient ||
|
|
||||||
await ServiceApiClient.create(oauth_credential)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {OAuthCredential} req.oauth_credential
|
* @param {OAuthCredential} req.oauth_credential
|
||||||
@ -294,7 +270,9 @@ export default class PeerClient {
|
|||||||
* @param {OAuthCredential} req.oauth_credential
|
* @param {OAuthCredential} req.oauth_credential
|
||||||
*/
|
*/
|
||||||
getOwnProfile = async (req) => {
|
getOwnProfile = async (req) => {
|
||||||
const serviceClient = await this.#getServiceClient(req.mxid, req.oauth_credential)
|
const serviceClient =
|
||||||
|
this.userClients.get(req.mxid)?.serviceClient ||
|
||||||
|
await ServiceApiClient.create(req.oauth_credential)
|
||||||
return await serviceClient.requestMyProfile()
|
return await serviceClient.requestMyProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,8 +283,10 @@ export default class PeerClient {
|
|||||||
* @param {Long} req.user_id
|
* @param {Long} req.user_id
|
||||||
*/
|
*/
|
||||||
getProfile = async (req) => {
|
getProfile = async (req) => {
|
||||||
const serviceClient = await this.#getServiceClient(req.mxid, req.oauth_credential)
|
const serviceClient =
|
||||||
return await serviceClient.requestProfile(req.user_id)
|
this.userClients.get(mxid)?.serviceClient ||
|
||||||
|
await ServiceApiClient.create(req.oauth_credential)
|
||||||
|
return await serviceClient.requestProfile(user_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -330,16 +310,6 @@ export default class PeerClient {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Object} req
|
|
||||||
* @param {string} req.mxid
|
|
||||||
*/
|
|
||||||
handleStop = async (req) => {
|
|
||||||
this.#getUser(req.mxid).close()
|
|
||||||
this.userClients.delete(req.mxid)
|
|
||||||
return this.#voidCommandResult
|
|
||||||
}
|
|
||||||
|
|
||||||
#makeCommandResult(result) {
|
#makeCommandResult(result) {
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
@ -348,9 +318,12 @@ export default class PeerClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#voidCommandResult = {
|
/**
|
||||||
success: true,
|
* @param {Object} req
|
||||||
status: 0,
|
* @param {string} req.mxid
|
||||||
|
*/
|
||||||
|
handleStop = async (req) => {
|
||||||
|
this.#getUser(req.mxid).close()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUnknownCommand = () => {
|
handleUnknownCommand = () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user