Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- run: sudo apt-get update && sudo apt-get install -y gettext python3-enchant
- run: python -m pip install sphinxcontrib-spelling
- run: sudo apt-get update && sudo apt-get install -y gettext
- run: python -m pip install -e '.[docs]'
- run: python -m sphinx -W -b spelling docs docs/_build
- run: python -m mkdocs build --strict
SQLite:
needs: [dist, docs]
runs-on: ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ docs/_build/
# PyBuilder
target/


# mkdocs documentation
/site/

tests/local.py
docs/_build/
Expand Down
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ repos:
hooks:
- id: mdformat
additional_dependencies:
- mdformat-ruff
- mdformat-ruff
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate dependency entry: "mdformat-ruff" is listed twice in the additional_dependencies list (lines 29 and line previously removed). This appears to be an error in the migration where line 29 should have been removed instead of line 28.

Suggested change
- mdformat-ruff

Copilot uses AI. Check for mistakes.
- mdformat-footnote
- mdformat-gfm
Expand Down
8 changes: 4 additions & 4 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
build:
os: ubuntu-20.04
os: ubuntu-24.04
tools:
python: "3.11"
sphinx:
configuration: docs/conf.py
python: "3"
mkdocs:
configuration: mkdocs.yml
python:
install:
- method: pip
Expand Down
112 changes: 112 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/codingjoe/django-mail-auth/raw/main/images/logo-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/codingjoe/django-mail-auth/raw/main/images/logo-light.svg">
<img alt="Django MailAuth: Secure login links; no passwords required!" src="https://github.com/codingjoe/django-mail-auth/raw/main/images/logo-light.svg">
</picture>
</p>

# Django Mail Auth

[![version](https://img.shields.io/pypi/v/django-mail-auth.svg)](https://pypi.python.org/pypi/django-mail-auth/)
[![Documentation Status](https://readthedocs.org/projects/django-mail-auth/badge/?version=latest)](https://django-mail-auth.readthedocs.io/en/latest/?badge=latest)
[![coverage](https://codecov.io/gh/codingjoe/django-mail-auth/branch/main/graph/badge.svg)](https://codecov.io/gh/codingjoe/django-mail-auth)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/codingjoe/django-mail-auth/main/LICENSE)

Django Mail Auth is a lightweight authentication backend for Django,
that does not require users to remember passwords.

Django Mail Auth features:

- custom user model support
- drop in Django admin support
- drop in Django User replacement
- drop in Wagtail login replacement
- extendable SMS support

![](sample.png){alt="screenshot from a login form" width="425px"}

This project was inspired by:

- [Is it time for password-less login?](http://notes.xoxco.com/post/27999787765/is-it-time-for-password-less-login)
by [Ben Brown](http://twitter.com/benbrown)
- [LOGIN WITHOUT PASSWORD MOST SECURE | WAIT.. WHAT?](https://www.lucius.digital/en/blog/login-without-password-most-secure-wait-what)
by [Joris Snoek](https://twitter.com/lucius_digital)
- [django-nopassword](https://github.com/relekang/django-nopassword) by
[Rolf Erik Lekang](http://rolflekang.com)

## Installation

Run this command to install `django-mail-auth`:

```
python3 -m pip install django-mail-auth[wagtail]
```

## Setup

First add `mailauth` to you installed apps:
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammatical error: "add mailauth to you installed apps" should be "add mailauth to your installed apps".

Copilot uses AI. Check for mistakes.

```python
INSTALLED_APPS = [
# Django's builtin apps…
"mailauth",
"mailauth.contrib.admin", # optional
"mailauth.contrib.user", # optional
# optional, must be included before "wagtail.admin"
"mailauth.contrib.wagtail",
# other apps…
]
```

`mailauth.contrib.admin` is optional and will replace the admin's login
with token based authentication too.

`mailauth.contrib.user` is optional and provides a new Django User
model. The new User model needs to be enabled via the `AUTH_USER_MODEL`
setting:

```python
# This setting should be either "EmailUser" or
# any custom subclass of "AbstractEmailUser"
AUTH_USER_MODEL = "mailauth_user.EmailUser"

# optional, Wagtail only
WAGTAILUSERS_PASSWORD_ENABLED = False
```

Next you will need to add the new authentication backend:

```python
AUTHENTICATION_BACKENDS = (
# default, but now optional
# This should be removed if you use mailauth.contrib.user or any other
# custom user model that does not have a username/password
"django.contrib.auth.backends.ModelBackend",
# The new access token based authentication backend
"mailauth.backends.MailAuthBackend",
)
```

Django's `ModelBackend` is only needed, if you still want to support
password based authentication. If you don't, simply remove it from the
list.

Last but not least, go to your URL root configuration `urls.py` and add
the following:

```python
from django.urls import path
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import statement: The code example uses include() function but doesn't import it. The import line should be from django.urls import path, include.

Suggested change
from django.urls import path
from django.urls import path, include

Copilot uses AI. Check for mistakes.


urlpatterns = [
path("accounts/", include("mailauth.urls")),
# optional, must be before "wagtail.admin.urls"
path("", include("mailauth.contrib.wagtail.urls")),
]
```

That's it!

> [!IMPORTANT]
> Don't forget to setup you Email backend!
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammatical error: "setup you Email backend" should be "setup your Email backend".

Suggested change
> Don't forget to setup you Email backend!
> Don't forget to setup your Email backend!

Copilot uses AI. Check for mistakes.
124 changes: 0 additions & 124 deletions README.rst

This file was deleted.

48 changes: 0 additions & 48 deletions docs/conf.py

This file was deleted.

27 changes: 27 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Contributing

To run test suite run:

```console
uv run pytest
```

To build the documentation run:

```
uv run mkdocs serve
```

## The sample app

To run a full example --- e.g. to debug frontend code -- you can run:
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect punctuation: "e.g. to debug frontend code --" should use a single dash "e.g. to debug frontend code -" instead of three dashes. Three dashes (---) is not standard for this context and may be rendered as an em dash depending on the markdown processor.

Suggested change
To run a full example --- e.g. to debug frontend code -- you can run:
To run a full example - e.g. to debug frontend code - you can run:

Copilot uses AI. Check for mistakes.

```
uv run tests/manage.py migrate
uv run tests/manage.py createsuperuser
# You will be asked for the email address of your new superuser
uv run tests/manage.py runserver
```

Next you can go to <https://localhost:8000/admin/> and log in with your
Copy link

Copilot AI Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid URL protocol: "https://localhost:8000/admin/" should use "http://localhost:8000/admin/" since localhost typically runs on HTTP by default, not HTTPS.

Suggested change
Next you can go to <https://localhost:8000/admin/> and log in with your
Next you can go to <http://localhost:8000/admin/> and log in with your

Copilot uses AI. Check for mistakes.
newly created superuser.
1 change: 0 additions & 1 deletion docs/contributing.rst

This file was deleted.

Loading
Loading