-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore password via email #2003
base: dev
Are you sure you want to change the base?
Conversation
Thanks for this PR! I think this would be useful on its own, but it may be even better to make the email sending code more generalized so that we can use it for other purposes, such as account invitations or other types of transactional mail. |
28bab75
to
e705899
Compare
@justinh-rahb I just refactored it a bit, so the mail config is accessible from the message = MessageSchema(
subject="Password Reset Request",
recipients=[user.email],
body=content,
subtype=MessageType.html,
)
fm = FastMail(MAIL_CONF)
await fm.send_message(message) We could also create some wrapper, or maybe define class MailSender:
def __init__(self, background_task: BackgroundTasks) -> None:
if config.MAIL_CONFIG is None:
raise Exception("No Mail Configured")
self.fm = FastMail(config.MAIL_CONFIG)
self.background_task = background_task
def __call__(self, message: MessageSchema, template_name: str | None = None):
self.background_task.add_task(self.fm.send_message, message, template_name)
# later in the app
@app.route('...')
async def do_things(mail_sender: Annotated[MailSender, Depends()]):
message = MessageSchema(
subject="Password Reset Request",
recipients=[user.email],
body=content,
subtype=MessageType.html,
)
mail_sender(message)
return {'message': 'whatever'} I like how it is now because of its versatility, what do you think? |
Agreed, this is much more flexible now and will provide a useful hook we can use for other similar purposes. Great work! |
56efdae
to
1814997
Compare
Added some documentation: open-webui/docs#65 |
1814997
to
bcdbc39
Compare
I'm unsure how to test this with Cypress, should I mock the backend calls? |
Cypress test coverage is far from 100% right now. I'd be comfortable merging this for the time being and waiting for a separate PR for test coverage later. And merging now will mean someone else might take that on even, saving you the work. |
That sounds nice! This is the first time I create a pull request in a public project, do you know what would be the next step for this to be merged? |
088f8ed
to
506f503
Compare
@@ -9,6 +9,7 @@ | |||
|
|||
from pathlib import Path | |||
import json | |||
from fastapi_mail import ConnectionConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Native implementation will be preferred here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I can use aiosmtplib
instead, the same used by fastapi_mail
. I installed the fastapi_mail
library because we would end up with a simpler but similar implementation that we would need to maintain.
We can use the smtplib
module in the standard library, or install aiosmtplib
to make it asynchronous. If we use the second one, we end up with an additional dependency anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use smtplib
for now and we can come back to this later.
.env.example
Outdated
LITELLM_LOCAL_MODEL_COST_MAP="True" | ||
|
||
ENABLE_MAIL="True" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ENABLE_EMAIL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all occurrence for MAIL
should be renamed to EMAIL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be included as a component from the same auth
route.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a way to make the reset password component shareable, so the link in the emails opens the "new password" flow.
If we use the same component, we need a way to open that component, via a query param? .../auth?reset-password=true
class ForgetPasswordResponse(BaseModel): | ||
message: str | ||
|
||
@router.post("/request-password-reset", response_model=ForgetPasswordResponse) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/password-reset/request
class ResetPasswordResponse(BaseModel): | ||
message: str | ||
|
||
@router.post("/reset-password", response_model=ResetPasswordResponse) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/password-reset/verify
The rest LGTM, Thanks for this PR! |
06b2861
to
4bcc785
Compare
EMAIL_SSL_TLS="False" | ||
|
||
FRONTEND_URL="http://localhost:5173" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WEBUI_URL
env var already exists!
Pull Request Checklist
Description
Allow users to restore their password via email.
Changelog Entry
Added
Additional Information
/api/v1/auths/request-password-reset
frontend/auth/reset-password?token=<the jwt>
.Reset Password
link.frontend/auth/reset-password?token=<the jwt>
.Reset Password
. It makes a POST request to/api/v1/auths/reset-password
.For this to work, configure some environment variables: