Use encoded email, otp in login URL in email & web app sign-in flow

Previously emails with url special characters would not get
successfully identified for login. Account creation was fine due to
email being in POST request body. But login with such emails did not
work due to query params not being escaped before being sent to server

This change escapes both the code and email in login URL sent to
server. So login with emails containing special characters like
`email+khoj@gmail.com' works. It fixes both the URL web app sent by
web app directly and the magic link sent to users to their email

This change also fixes accessibility issue of having a DialogTitle in
DialogContent for screen readers.

Resolves #1090
This commit is contained in:
Debanjum
2025-01-19 13:05:15 +07:00
parent 51f3af11b5
commit 2d4633d298
3 changed files with 12 additions and 5 deletions

View File

@@ -2,7 +2,7 @@
import styles from "./loginPrompt.module.css";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import Autoplay from "embla-carousel-autoplay";
import {
@@ -27,6 +27,7 @@ import {
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp";
import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
export interface LoginPromptProps {
onOpenChange: (open: boolean) => void;
@@ -181,6 +182,9 @@ export default function LoginPrompt(props: LoginPromptProps) {
<DialogContent
className={`flex flex-col gap-4 ${!useEmailSignIn ? "p-0 pb-4 m-0 max-w-xl" : "w-fit"}`}
>
<VisuallyHidden.Root>
<DialogTitle>Login Dialog</DialogTitle>
</VisuallyHidden.Root>
<div>
{useEmailSignIn ? (
<EmailSignInContext
@@ -232,7 +236,7 @@ function EmailSignInContext({
const [numFailures, setNumFailures] = useState(0);
function checkOTPAndRedirect() {
const verifyUrl = `/auth/magic?code=${otp}&email=${email}`;
const verifyUrl = `/auth/magic?code=${encodeURIComponent(otp)}&email=${encodeURIComponent(email)}`;
if (numFailures >= ALLOWED_OTP_ATTEMPTS) {
setOTPError("Too many failed attempts. Please try again tomorrow.");

View File

@@ -1,6 +1,7 @@
import csv
import json
from datetime import datetime, timedelta
from urllib.parse import quote
from apscheduler.job import Job
from django.contrib import admin, messages
@@ -154,8 +155,9 @@ class KhojUserAdmin(UserAdmin, unfold_admin.ModelAdmin):
for user in queryset:
if user.email:
host = request.get_host()
unique_id = user.email_verification_code
login_url = f"{host}/auth/magic?code={unique_id}&email={user.email}"
otp = quote(user.email_verification_code)
encoded_email = quote(user.email)
login_url = f"{host}/auth/magic?code={otp}&email={encoded_email}"
messages.info(request, f"Email login URL for {user.email}: {login_url}")
get_email_login_url.short_description = "Get email login URL" # type: ignore

View File

@@ -1,5 +1,6 @@
import logging
import os
from urllib.parse import quote
import markdown_it
import resend
@@ -29,7 +30,7 @@ def is_resend_enabled():
async def send_magic_link_email(email, unique_id, host):
sign_in_link = f"{host}auth/magic?code={unique_id}&email={email}"
sign_in_link = f"{host}auth/magic?code={quote(unique_id)}&email={quote(email)}"
if not is_resend_enabled():
logger.debug(f"Email sending disabled. Share this sign-in link with the user: {sign_in_link}")