Improve login page style and fix bugs

This commit is contained in:
Tulir Asokan
2018-02-21 23:35:44 +02:00
parent e96e1459eb
commit 29c71b48de
6 changed files with 142 additions and 44 deletions
+7 -4
View File
@@ -72,18 +72,21 @@ bridge:
# 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.
native_replies: True
native_replies: true
# If native replies are disabled, should the custom replies contain a link to the message being
# replied to?
link_in_reply: False
link_in_reply: false
# 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.
edits_as_replies: False
edits_as_replies: false
# 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.
# A large number of simultaneous redactions could put strain on your homeserver.
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.
command_prefix: "!tg"
+27 -2
View File
@@ -54,8 +54,30 @@ def register(evt):
async def login(evt):
if evt.sender.logged_in:
return await evt.reply("You are already logged in.")
elif len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp login <phone number>`")
evt.sender.command_status = {
"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]
try:
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")
return await evt.reply("Unhandled exception while requesting code. "
"Check console for more details.")
finally:
if evt.sender.command_status["next"] == enter_phone:
evt.sender.command_status = None
@command_handler(needs_auth=False)
+3 -3
View File
@@ -50,9 +50,9 @@ def help(evt):
**cancel** - Cancel an ongoing action (such as login).
#### Authentication
**login** <_phone_> - Request an authentication code.
**logout** - Log out from Telegram.
**ping** - Check if you're logged into Telegram.
**login** - Request an authentication code.
**logout** - Log out from Telegram.
**ping** - Check if you're logged into Telegram.
#### Initiating chats
**search** [_-r|--remote_] <_query_> - Search your contacts or the Telegram servers for users.
+22 -14
View File
@@ -42,16 +42,22 @@ class PublicBridgeWebsite:
pkg_resources.resource_filename("mautrix_telegram", "public/"))
async def get_login(self, request):
return self.render_login(
request.rel_url.query["mxid"] if "mxid" in request.rel_url.query else "")
user = (User.get_by_mxid(request.rel_url.query["mxid"], create=False)
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="",
error="", message="", username="", status=200):
return web.Response(status=status,
content_type="text/html",
text=self.login.render(mxid=mxid, state=state, phone=phone, code=code,
message=message, username=username, error=error,
password=password))
return self.render_login(mxid=user.mxid, username=user.username)
def render_login(self, status=200, username="", state="", error="", message="", mxid=""):
return web.Response(status=status, content_type="text/html",
text=self.login.render(username=username, state=state, error=error,
message=message, mxid=mxid))
async def post_login(self, request):
self.log.debug(request)
@@ -59,9 +65,11 @@ class PublicBridgeWebsite:
if "mxid" not in data:
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:
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:
try:
@@ -93,7 +101,7 @@ class PublicBridgeWebsite:
try:
user_info = await user.client.sign_in(code=data["code"])
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
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
username=user_info.username)
@@ -105,14 +113,14 @@ class PublicBridgeWebsite:
error="Phone code expired.")
except SessionPasswordNeededError:
if "password" not in data:
if user.command_status.action == "Login":
if user.command_status and user.command_status.action == "Login":
user.command_status = {
"next": enter_password,
"action": "Login (password entry)",
}
return self.render_login(
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:
self.log.exception("Error sending phone code")
return self.render_login(mxid=user.mxid, state="code", status=500,
@@ -124,7 +132,7 @@ class PublicBridgeWebsite:
try:
user_info = await user.client.sign_in(password=data["password"])
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
return self.render_login(mxid=user.mxid, state="logged-in", status=200,
username=user_info.username)
+24
View File
@@ -7,3 +7,27 @@ form[data-status="code"] > div.status-code,
form[data-status="password"] > div.status-password {
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;
}
+59 -21
View File
@@ -7,33 +7,71 @@
<meta property="og:description" content="A hybrid puppeting/relaybot Matrix-Telegram bridge">
<meta property="og:image" content="favicon.png">
<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"/>
</head>
<body>
<main>
% if state == "logged-in":
<h1>Logged in successfully!</h1>
<p>Logged in as @${username}</p>
<main class="container">
% if username:
% if state == "logged-in":
<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:
<h1>Log in to Telegram</h1>
% if error:
<div class="error">${error}</div>
% endif
% if message:
<div class="message">${message}</div>
% endif
% if error:
<div class="error">${error}</div>
% endif
% if message:
<div class="message">${message}</div>
% endif
<form method="post">
<input type="text" name="mxid" placeholder="Enter Matrix ID" value="${mxid}"/>
% if state == "request":
<input type="text" name="phone" placeholder="Enter phone number"/>
<button type="submit">Request code</button>
% elif state == "code":
<input type="number" name="code" placeholder="Enter phone code"/>
<button type="submit">Sign in</button>
% elif state == "password":
<input type="password" name="password" placeholder="Enter password"/>
<button type="submit">Sign in</button>
% endif
<fieldset>
<label for="mxid">Matrix ID</label>
<input type="text" id="mxid" name="mxid" placeholder="Enter Matrix ID"
value="${mxid}"/>
% if state == "request":
<label for="value">Phone number</label>
<input type="tel" id="value" name="phone" placeholder="Enter phone number"/>
<button type="submit">Request code</button>
% elif state == "code":
<label for="value">Phone code</label>
<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>
% endif
</main>