Improve login page style and fix bugs
This commit is contained in:
+7
-4
@@ -72,18 +72,21 @@ bridge:
|
|||||||
|
|
||||||
# Whether or not to use native Matrix replies. At the time of writing, only riot-web supports
|
# Whether or not to use native Matrix replies. At the time of writing, only riot-web supports
|
||||||
# replies and the format of them is subject to change.
|
# replies and the format of them is subject to change.
|
||||||
native_replies: True
|
native_replies: true
|
||||||
# If native replies are disabled, should the custom replies contain a link to the message being
|
# If native replies are disabled, should the custom replies contain a link to the message being
|
||||||
# replied to?
|
# replied to?
|
||||||
link_in_reply: False
|
link_in_reply: false
|
||||||
# Show message editing as a reply to the original message.
|
# Show message editing as a reply to the original message.
|
||||||
# If this is false, message edits are not shown at all, as Matrix does not support editing yet.
|
# If this is false, message edits are not shown at all, as Matrix does not support editing yet.
|
||||||
edits_as_replies: False
|
edits_as_replies: false
|
||||||
# Whether or not Matrix bot messages (type m.notice) should be bridged.
|
# Whether or not Matrix bot messages (type m.notice) should be bridged.
|
||||||
bridge_notices: False
|
bridge_notices: false
|
||||||
# The maximum number of simultaneous Telegram deletions to handle.
|
# The maximum number of simultaneous Telegram deletions to handle.
|
||||||
# A large number of simultaneous redactions could put strain on your homeserver.
|
# A large number of simultaneous redactions could put strain on your homeserver.
|
||||||
max_telegram_delete: 10
|
max_telegram_delete: 10
|
||||||
|
# Allow logging in within Matrix. If false, the only way to log in is using the out-of-Matrix
|
||||||
|
# login website (see appservice.public config section)
|
||||||
|
allow_matrix_login: true
|
||||||
|
|
||||||
# The prefix for commands. Only required in non-management rooms.
|
# The prefix for commands. Only required in non-management rooms.
|
||||||
command_prefix: "!tg"
|
command_prefix: "!tg"
|
||||||
|
|||||||
@@ -54,8 +54,30 @@ def register(evt):
|
|||||||
async def login(evt):
|
async def login(evt):
|
||||||
if evt.sender.logged_in:
|
if evt.sender.logged_in:
|
||||||
return await evt.reply("You are already logged in.")
|
return await evt.reply("You are already logged in.")
|
||||||
elif len(evt.args) == 0:
|
evt.sender.command_status = {
|
||||||
return await evt.reply("**Usage:** `$cmdprefix+sp login <phone number>`")
|
"next": enter_phone,
|
||||||
|
"action": "Login",
|
||||||
|
}
|
||||||
|
if evt.config["appservice.public.enabled"]:
|
||||||
|
prefix = evt.config["appservice.public.external"]
|
||||||
|
url = f"{prefix}/login?mxid={evt.sender.mxid}"
|
||||||
|
if evt.config.get("bridge.allow_matrix_login", True):
|
||||||
|
return await evt.reply("\n\n".join((
|
||||||
|
"This bridge instance allows you to log in inside or outside Matrix.",
|
||||||
|
"If you would like to log in within Matrix, please send your phone number here.",
|
||||||
|
f"If you would like to log in outside of Matrix, [click here]({url}).")))
|
||||||
|
return await evt.reply("This bridge instance does not allow logging in inside Matrix.\n\n"
|
||||||
|
f"Please visit [the login page]({url}) to log in.")
|
||||||
|
return await evt.reply(
|
||||||
|
"This bridge instance does not allow you to log in outside of Matrix.\n\n"
|
||||||
|
"Please send your phone number here to start the login process.")
|
||||||
|
|
||||||
|
|
||||||
|
@command_handler(needs_auth=False)
|
||||||
|
async def enter_phone(evt):
|
||||||
|
if len(evt.args) == 0:
|
||||||
|
return await evt.reply("**Usage:** `$cmdprefix+sp enter-phone <phone>`")
|
||||||
|
|
||||||
phone_number = evt.args[0]
|
phone_number = evt.args[0]
|
||||||
try:
|
try:
|
||||||
await evt.sender.ensure_started(even_if_no_session=True)
|
await evt.sender.ensure_started(even_if_no_session=True)
|
||||||
@@ -81,6 +103,9 @@ async def login(evt):
|
|||||||
evt.log.exception("Error requesting phone code")
|
evt.log.exception("Error requesting phone code")
|
||||||
return await evt.reply("Unhandled exception while requesting code. "
|
return await evt.reply("Unhandled exception while requesting code. "
|
||||||
"Check console for more details.")
|
"Check console for more details.")
|
||||||
|
finally:
|
||||||
|
if evt.sender.command_status["next"] == enter_phone:
|
||||||
|
evt.sender.command_status = None
|
||||||
|
|
||||||
|
|
||||||
@command_handler(needs_auth=False)
|
@command_handler(needs_auth=False)
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ def help(evt):
|
|||||||
**cancel** - Cancel an ongoing action (such as login).
|
**cancel** - Cancel an ongoing action (such as login).
|
||||||
|
|
||||||
#### Authentication
|
#### Authentication
|
||||||
**login** <_phone_> - Request an authentication code.
|
**login** - Request an authentication code.
|
||||||
**logout** - Log out from Telegram.
|
**logout** - Log out from Telegram.
|
||||||
**ping** - Check if you're logged into Telegram.
|
**ping** - Check if you're logged into Telegram.
|
||||||
|
|
||||||
#### Initiating chats
|
#### Initiating chats
|
||||||
**search** [_-r|--remote_] <_query_> - Search your contacts or the Telegram servers for users.
|
**search** [_-r|--remote_] <_query_> - Search your contacts or the Telegram servers for users.
|
||||||
|
|||||||
@@ -42,16 +42,22 @@ class PublicBridgeWebsite:
|
|||||||
pkg_resources.resource_filename("mautrix_telegram", "public/"))
|
pkg_resources.resource_filename("mautrix_telegram", "public/"))
|
||||||
|
|
||||||
async def get_login(self, request):
|
async def get_login(self, request):
|
||||||
return self.render_login(
|
user = (User.get_by_mxid(request.rel_url.query["mxid"], create=False)
|
||||||
request.rel_url.query["mxid"] if "mxid" in request.rel_url.query else "")
|
if "mxid" in request.rel_url.query else None)
|
||||||
|
if not user:
|
||||||
|
return self.render_login(mxid=request.rel_url.query["mxid"], state="request")
|
||||||
|
elif not user.whitelisted:
|
||||||
|
return self.render_login(mxid=user.mxid, error="You are not whitelisted.", status=403)
|
||||||
|
await user.ensure_started()
|
||||||
|
if not user.logged_in:
|
||||||
|
return self.render_login(mxid=user.mxid, state="request")
|
||||||
|
|
||||||
def render_login(self, mxid, state="request", phone="", code="", password="",
|
return self.render_login(mxid=user.mxid, username=user.username)
|
||||||
error="", message="", username="", status=200):
|
|
||||||
return web.Response(status=status,
|
def render_login(self, status=200, username="", state="", error="", message="", mxid=""):
|
||||||
content_type="text/html",
|
return web.Response(status=status, content_type="text/html",
|
||||||
text=self.login.render(mxid=mxid, state=state, phone=phone, code=code,
|
text=self.login.render(username=username, state=state, error=error,
|
||||||
message=message, username=username, error=error,
|
message=message, mxid=mxid))
|
||||||
password=password))
|
|
||||||
|
|
||||||
async def post_login(self, request):
|
async def post_login(self, request):
|
||||||
self.log.debug(request)
|
self.log.debug(request)
|
||||||
@@ -59,9 +65,11 @@ class PublicBridgeWebsite:
|
|||||||
if "mxid" not in data:
|
if "mxid" not in data:
|
||||||
return self.render_login(error="Please enter your Matrix ID.", status=400)
|
return self.render_login(error="Please enter your Matrix ID.", status=400)
|
||||||
|
|
||||||
user = User.get_by_mxid(data["mxid"])
|
user = await User.get_by_mxid(data["mxid"]).ensure_started()
|
||||||
if not user.whitelisted:
|
if not user.whitelisted:
|
||||||
return self.render_login(mxid=user.mxid, error="You are not whitelisted.", status=403)
|
return self.render_login(mxid=user.mxid, error="You are not whitelisted.", status=403)
|
||||||
|
elif user.logged_in:
|
||||||
|
return self.render_login(mxid=user.mxid, username=user.username)
|
||||||
|
|
||||||
if "phone" in data:
|
if "phone" in data:
|
||||||
try:
|
try:
|
||||||
@@ -93,7 +101,7 @@ class PublicBridgeWebsite:
|
|||||||
try:
|
try:
|
||||||
user_info = await user.client.sign_in(code=data["code"])
|
user_info = await user.client.sign_in(code=data["code"])
|
||||||
asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
|
asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
|
||||||
if user.command_status.action == "Login":
|
if user.command_status and user.command_status.action == "Login":
|
||||||
user.command_status = None
|
user.command_status = None
|
||||||
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
|
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
|
||||||
username=user_info.username)
|
username=user_info.username)
|
||||||
@@ -105,14 +113,14 @@ class PublicBridgeWebsite:
|
|||||||
error="Phone code expired.")
|
error="Phone code expired.")
|
||||||
except SessionPasswordNeededError:
|
except SessionPasswordNeededError:
|
||||||
if "password" not in data:
|
if "password" not in data:
|
||||||
if user.command_status.action == "Login":
|
if user.command_status and user.command_status.action == "Login":
|
||||||
user.command_status = {
|
user.command_status = {
|
||||||
"next": enter_password,
|
"next": enter_password,
|
||||||
"action": "Login (password entry)",
|
"action": "Login (password entry)",
|
||||||
}
|
}
|
||||||
return self.render_login(
|
return self.render_login(
|
||||||
mxid=user.mxid, state="password", status=200,
|
mxid=user.mxid, state="password", status=200,
|
||||||
error="Code accepted, but you have 2-factor authentication is enabled.")
|
message="Code accepted, but you have 2-factor authentication is enabled.")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.log.exception("Error sending phone code")
|
self.log.exception("Error sending phone code")
|
||||||
return self.render_login(mxid=user.mxid, state="code", status=500,
|
return self.render_login(mxid=user.mxid, state="code", status=500,
|
||||||
@@ -124,7 +132,7 @@ class PublicBridgeWebsite:
|
|||||||
try:
|
try:
|
||||||
user_info = await user.client.sign_in(password=data["password"])
|
user_info = await user.client.sign_in(password=data["password"])
|
||||||
asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
|
asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
|
||||||
if user.command_status.action == "Login (password entry)":
|
if user.command_status and user.command_status.action == "Login (password entry)":
|
||||||
user.command_status = None
|
user.command_status = None
|
||||||
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
|
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
|
||||||
username=user_info.username)
|
username=user_info.username)
|
||||||
|
|||||||
@@ -7,3 +7,27 @@ form[data-status="code"] > div.status-code,
|
|||||||
form[data-status="password"] > div.status-password {
|
form[data-status="password"] > div.status-password {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin-top: 3rem;
|
||||||
|
max-width: 60rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error, .message {
|
||||||
|
border-radius: .25rem;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
margin: .5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
border-color: #f5c6cb;
|
||||||
|
background-color: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
border-color: #c3e6cb;
|
||||||
|
background-color: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,33 +7,71 @@
|
|||||||
<meta property="og:description" content="A hybrid puppeting/relaybot Matrix-Telegram bridge">
|
<meta property="og:description" content="A hybrid puppeting/relaybot Matrix-Telegram bridge">
|
||||||
<meta property="og:image" content="favicon.png">
|
<meta property="og:image" content="favicon.png">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,700">
|
||||||
|
<link rel="stylesheet" href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css">
|
||||||
<link rel="stylesheet" href="login.css"/>
|
<link rel="stylesheet" href="login.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main class="container">
|
||||||
% if state == "logged-in":
|
% if username:
|
||||||
<h1>Logged in successfully!</h1>
|
% if state == "logged-in":
|
||||||
<p>Logged in as @${username}</p>
|
<h1>Logged in successfully!</h1>
|
||||||
|
<p>
|
||||||
|
Logged in as @${username}.
|
||||||
|
You should be invited to Telegram portals on Matrix very soon.
|
||||||
|
</p>
|
||||||
|
% else:
|
||||||
|
<h1>You're already logged in!</h1>
|
||||||
|
<p>
|
||||||
|
You're logged in as @${username}.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you want to log in with another account, log out using the <code>logout</code>
|
||||||
|
management command first.
|
||||||
|
</p>
|
||||||
|
% endif
|
||||||
% else:
|
% else:
|
||||||
<h1>Log in to Telegram</h1>
|
<h1>Log in to Telegram</h1>
|
||||||
% if error:
|
% if error:
|
||||||
<div class="error">${error}</div>
|
<div class="error">${error}</div>
|
||||||
% endif
|
% endif
|
||||||
% if message:
|
% if message:
|
||||||
<div class="message">${message}</div>
|
<div class="message">${message}</div>
|
||||||
% endif
|
% endif
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="text" name="mxid" placeholder="Enter Matrix ID" value="${mxid}"/>
|
<fieldset>
|
||||||
% if state == "request":
|
<label for="mxid">Matrix ID</label>
|
||||||
<input type="text" name="phone" placeholder="Enter phone number"/>
|
<input type="text" id="mxid" name="mxid" placeholder="Enter Matrix ID"
|
||||||
<button type="submit">Request code</button>
|
value="${mxid}"/>
|
||||||
% elif state == "code":
|
% if state == "request":
|
||||||
<input type="number" name="code" placeholder="Enter phone code"/>
|
<label for="value">Phone number</label>
|
||||||
<button type="submit">Sign in</button>
|
<input type="tel" id="value" name="phone" placeholder="Enter phone number"/>
|
||||||
% elif state == "password":
|
<button type="submit">Request code</button>
|
||||||
<input type="password" name="password" placeholder="Enter password"/>
|
% elif state == "code":
|
||||||
<button type="submit">Sign in</button>
|
<label for="value">Phone code</label>
|
||||||
% endif
|
<input type="number" id="value" name="code" placeholder="Enter phone code"/>
|
||||||
|
<button type="submit">Sign in</button>
|
||||||
|
<div class="float-right">
|
||||||
|
<button class="button-clear" type="button"
|
||||||
|
onclick="location.replace(location.href)">
|
||||||
|
Go back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
% elif state == "password":
|
||||||
|
<label for="value">Password</label>
|
||||||
|
<input type="password" id="value" name="password"
|
||||||
|
placeholder="Enter password"/>
|
||||||
|
<button type="submit">Sign in</button>
|
||||||
|
<div class="float-right">
|
||||||
|
<button class="button-clear" type="button"
|
||||||
|
onclick="location.replace(location.href)">
|
||||||
|
Go back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
% endif
|
||||||
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
% endif
|
% endif
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user