Compare commits
No commits in common. "73b212c4910098bca0de6f47b2727f2ef10c885c" and "7595c4433aa957e84727c8510846fdf2b1476811" have entirely different histories.
73b212c491
...
7595c4433a
8
.gitignore
vendored
8
.gitignore
vendored
@ -5,11 +5,9 @@ build/
|
|||||||
dist/
|
dist/
|
||||||
wheels/
|
wheels/
|
||||||
*.egg-info
|
*.egg-info
|
||||||
|
|
||||||
# Virtual environments
|
|
||||||
.venv
|
|
||||||
|
|
||||||
# project files
|
|
||||||
_staticfiles/
|
_staticfiles/
|
||||||
_logs/
|
_logs/
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
|
12
Justfile
12
Justfile
@ -1,20 +1,10 @@
|
|||||||
# run pre-commit linters
|
|
||||||
lint:
|
lint:
|
||||||
uv run pre-commit run --all-files
|
uv run pre-commit run --all-files
|
||||||
|
|
||||||
# run pytest
|
|
||||||
test *ARGS:
|
test *ARGS:
|
||||||
uv run pytest {{ARGS}}
|
uv run pytest {{ARGS}}
|
||||||
|
|
||||||
# reset database and ephemeral files
|
|
||||||
reset:
|
|
||||||
rm -rf _logs/*
|
|
||||||
rm -rf _staticfiles
|
|
||||||
rm -rf db.sqlite3
|
|
||||||
uv run python manage.py migrate
|
|
||||||
uv run python manage.py createsuperuser
|
|
||||||
|
|
||||||
# run development server
|
|
||||||
runserver *ARGS:
|
runserver *ARGS:
|
||||||
uv run python manage.py runserver {{ARGS}}
|
uv run python manage.py runserver {{ARGS}}
|
||||||
|
|
||||||
|
121
LICENSE
121
LICENSE
@ -1,121 +0,0 @@
|
|||||||
Creative Commons Legal Code
|
|
||||||
|
|
||||||
CC0 1.0 Universal
|
|
||||||
|
|
||||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
|
||||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
|
||||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
|
||||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
|
||||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
|
||||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
|
||||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
|
||||||
HEREUNDER.
|
|
||||||
|
|
||||||
Statement of Purpose
|
|
||||||
|
|
||||||
The laws of most jurisdictions throughout the world automatically confer
|
|
||||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
|
||||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
|
||||||
authorship and/or a database (each, a "Work").
|
|
||||||
|
|
||||||
Certain owners wish to permanently relinquish those rights to a Work for
|
|
||||||
the purpose of contributing to a commons of creative, cultural and
|
|
||||||
scientific works ("Commons") that the public can reliably and without fear
|
|
||||||
of later claims of infringement build upon, modify, incorporate in other
|
|
||||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
|
||||||
and for any purposes, including without limitation commercial purposes.
|
|
||||||
These owners may contribute to the Commons to promote the ideal of a free
|
|
||||||
culture and the further production of creative, cultural and scientific
|
|
||||||
works, or to gain reputation or greater distribution for their Work in
|
|
||||||
part through the use and efforts of others.
|
|
||||||
|
|
||||||
For these and/or other purposes and motivations, and without any
|
|
||||||
expectation of additional consideration or compensation, the person
|
|
||||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
|
||||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
|
||||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
|
||||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
|
||||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
|
||||||
|
|
||||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
|
||||||
protected by copyright and related or neighboring rights ("Copyright and
|
|
||||||
Related Rights"). Copyright and Related Rights include, but are not
|
|
||||||
limited to, the following:
|
|
||||||
|
|
||||||
i. the right to reproduce, adapt, distribute, perform, display,
|
|
||||||
communicate, and translate a Work;
|
|
||||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
|
||||||
iii. publicity and privacy rights pertaining to a person's image or
|
|
||||||
likeness depicted in a Work;
|
|
||||||
iv. rights protecting against unfair competition in regards to a Work,
|
|
||||||
subject to the limitations in paragraph 4(a), below;
|
|
||||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
|
||||||
in a Work;
|
|
||||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
|
||||||
European Parliament and of the Council of 11 March 1996 on the legal
|
|
||||||
protection of databases, and under any national implementation
|
|
||||||
thereof, including any amended or successor version of such
|
|
||||||
directive); and
|
|
||||||
vii. other similar, equivalent or corresponding rights throughout the
|
|
||||||
world based on applicable law or treaty, and any national
|
|
||||||
implementations thereof.
|
|
||||||
|
|
||||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
|
||||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
|
||||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
|
||||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
|
||||||
of action, whether now known or unknown (including existing as well as
|
|
||||||
future claims and causes of action), in the Work (i) in all territories
|
|
||||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
|
||||||
treaty (including future time extensions), (iii) in any current or future
|
|
||||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
|
||||||
including without limitation commercial, advertising or promotional
|
|
||||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
|
||||||
member of the public at large and to the detriment of Affirmer's heirs and
|
|
||||||
successors, fully intending that such Waiver shall not be subject to
|
|
||||||
revocation, rescission, cancellation, termination, or any other legal or
|
|
||||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
|
||||||
as contemplated by Affirmer's express Statement of Purpose.
|
|
||||||
|
|
||||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
|
||||||
be judged legally invalid or ineffective under applicable law, then the
|
|
||||||
Waiver shall be preserved to the maximum extent permitted taking into
|
|
||||||
account Affirmer's express Statement of Purpose. In addition, to the
|
|
||||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
|
||||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
|
||||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
|
||||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
|
||||||
maximum duration provided by applicable law or treaty (including future
|
|
||||||
time extensions), (iii) in any current or future medium and for any number
|
|
||||||
of copies, and (iv) for any purpose whatsoever, including without
|
|
||||||
limitation commercial, advertising or promotional purposes (the
|
|
||||||
"License"). The License shall be deemed effective as of the date CC0 was
|
|
||||||
applied by Affirmer to the Work. Should any part of the License for any
|
|
||||||
reason be judged legally invalid or ineffective under applicable law, such
|
|
||||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
|
||||||
of the License, and in such case Affirmer hereby affirms that he or she
|
|
||||||
will not (i) exercise any of his or her remaining Copyright and Related
|
|
||||||
Rights in the Work or (ii) assert any associated claims and causes of
|
|
||||||
action with respect to the Work, in either case contrary to Affirmer's
|
|
||||||
express Statement of Purpose.
|
|
||||||
|
|
||||||
4. Limitations and Disclaimers.
|
|
||||||
|
|
||||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
|
||||||
surrendered, licensed or otherwise affected by this document.
|
|
||||||
b. Affirmer offers the Work as-is and makes no representations or
|
|
||||||
warranties of any kind concerning the Work, express, implied,
|
|
||||||
statutory or otherwise, including without limitation warranties of
|
|
||||||
title, merchantability, fitness for a particular purpose, non
|
|
||||||
infringement, or the absence of latent or other defects, accuracy, or
|
|
||||||
the present or absence of errors, whether or not discoverable, all to
|
|
||||||
the greatest extent permissible under applicable law.
|
|
||||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
|
||||||
that may apply to the Work or any use thereof, including without
|
|
||||||
limitation any person's Copyright and Related Rights in the Work.
|
|
||||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
|
||||||
consents, permissions or other rights required for any use of the
|
|
||||||
Work.
|
|
||||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
|
||||||
party to this document and has no duty or obligation with respect to
|
|
||||||
this CC0 or use of the Work.
|
|
66
README.md
66
README.md
@ -5,39 +5,25 @@ This is our opinionated template for starting new Django projects.
|
|||||||
It adds a few libraries useful for every Django project, with reasonable starting configurations.
|
It adds a few libraries useful for every Django project, with reasonable starting configurations.
|
||||||
Additionally, the repository has linting/CI rules and a project layout that has worked well for our many Django projects.
|
Additionally, the repository has linting/CI rules and a project layout that has worked well for our many Django projects.
|
||||||
|
|
||||||
## License & Usage
|
## License
|
||||||
|
|
||||||
This project is placed into the public domain ([CC0](https://creativecommons.org/public-domain/cc0/)) so you may use it however you see fit.
|
This project is placed into the public domain ([CC0](https://creativecommons.org/public-domain/cc0/)) so you may use it however you see fit.
|
||||||
|
|
||||||
You can clone this repository and use it as a template, or pick & choose what you like and copy files as needed.
|
You can clone this repository, use it as a template, or pick & choose what you like. Attribution is appreciated but not required.
|
||||||
|
|
||||||
Attribution is appreciated but not required.
|
|
||||||
|
|
||||||
Please note that the underlying libraries are under their own (MIT/BSD) licenses.
|
Please note that the underlying libraries are under their own (MIT/BSD) licenses.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
To make full usage of this you will need to install
|
|
||||||
|
|
||||||
- `uv` - <https://docs.astral.sh/uv/getting-started/installation/>
|
|
||||||
- `just`
|
|
||||||
- You can run `just` using `uv` if you wish, `uvx --from rust-just just`
|
|
||||||
|
|
||||||
|
|
||||||
If you are using this library as a baseline, there are a few steps you'll need to follow:
|
If you are using this library as a baseline, there are a few steps you'll need to follow:
|
||||||
|
|
||||||
1. Read through the various sections below to familiarize yourself with the setup.
|
1. Replace pyproject.toml "djok" with your project name.
|
||||||
|
2. **Recommended:** run `uv run pre-commit install`
|
||||||
|
3. Read through the various sections below to familiarize yourself with the setup.
|
||||||
A few of the libraries may require additional setup, documented under the **You:** steps below.
|
A few of the libraries may require additional setup, documented under the **You:** steps below.
|
||||||
2. Before starting, you will need to choose which kind of user account you want. See `DJOK_USER_TYPE` below.
|
|
||||||
3. Replace this README & the LICENSE file with those appropriate to your project.
|
|
||||||
(**Caution**: Since this repository is licensed CC-0, failure to do so would mean licensing your code in the same way, likely not what you want.)
|
|
||||||
4. Open pyproject.toml & replace "djok" with your project name.
|
|
||||||
5. **Recommended:** run `uv run pre-commit install`
|
|
||||||
|
|
||||||
## File System Layout
|
## File System Layout
|
||||||
|
|
||||||
- `apps/` - Create your app(s) in this directory.
|
|
||||||
- `apps/accounts/` - An app that defines our custom user model, compatible with `allauth` and `django.contrib.admin`.
|
|
||||||
- `config/` - This directory is the Django "project". It contains settings files as well as your root `urls.py`.
|
- `config/` - This directory is the Django "project". It contains settings files as well as your root `urls.py`.
|
||||||
- `static/` - This directory is where you will place your static CSS, images, and JS. Those files will be served via `whitenoise`.
|
- `static/` - This directory is where you will place your static CSS, images, and JS. Those files will be served via `whitenoise`.
|
||||||
- `static/root/` - This directory will be served as-is at the root of your application. It is useful for files like `robots.txt` that need to be in a particular place.
|
- `static/root/` - This directory will be served as-is at the root of your application. It is useful for files like `robots.txt` that need to be in a particular place.
|
||||||
@ -124,40 +110,14 @@ This library integrates [structured logging](https://www.structlog.org/en/stable
|
|||||||
|
|
||||||
Augment's django's built in `auth` with commonly-needed views for signup, email confirmation, etc.
|
Augment's django's built in `auth` with commonly-needed views for signup, email confirmation, etc.
|
||||||
|
|
||||||
**We:** Provide several configurations.
|
**We:** Configured for email login.
|
||||||
|
|
||||||
**You:** Select one by setting `DJOK_USER_TYPE`.
|
**You:** Review settings & ensure that they meet your application's login needs.
|
||||||
|
|
||||||
#### DJOK_USER_TYPE
|
## Pre-Configured URLs
|
||||||
|
|
||||||
Should be set to either:
|
|
||||||
|
|
||||||
- `username` - Standard username/password login w/ optional email.
|
|
||||||
- `email` - Standard email/password login, username is set to email.
|
|
||||||
Comes with allauth-powered token-based login as well.
|
|
||||||
- `email+username` - Email-based with optional username field for display
|
|
||||||
purposes.
|
|
||||||
|
|
||||||
This must be set **before** running initial DB migrations.
|
|
||||||
|
|
||||||
Once set, you can run:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
just dj makemigrations accounts
|
|
||||||
just dj migrate
|
|
||||||
```
|
|
||||||
|
|
||||||
Changing once the application is live will require careful planning and custom data migration.
|
|
||||||
|
|
||||||
#### DJOK_PASSWORD_PROMPTS
|
|
||||||
|
|
||||||
Determines how many password prompts are shown.
|
|
||||||
|
|
||||||
- 0 - Email/Token based login.
|
|
||||||
- 1 - Single password box.
|
|
||||||
- 2 - Password box with confirmation.
|
|
||||||
|
|
||||||
#### Webauthn
|
|
||||||
|
|
||||||
See the comments in `config/settings.py` to enable signup & login via Webauthn.
|
|
||||||
|
|
||||||
|
- `/djadmin` - [`django.admin`](https://docs.djangoproject.com/en/5.2/ref/contrib/admin/)
|
||||||
|
- `/accounts/login`
|
||||||
|
- `/accounts/signup`
|
||||||
|
- `/accounts/login/code`
|
||||||
|
- `/accounts/password/reset`
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
from django.contrib import admin
|
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
||||||
from .models import User
|
|
||||||
|
|
||||||
|
|
||||||
class UserAdmin(BaseUserAdmin):
|
|
||||||
list_display = ["is_active", "username", "full_name", "is_staff", "is_superuser"]
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(User, UserAdmin)
|
|
@ -1,84 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
from django.contrib.auth.models import (
|
|
||||||
AbstractBaseUser,
|
|
||||||
PermissionsMixin,
|
|
||||||
UnicodeUsernameValidator,
|
|
||||||
UserManager,
|
|
||||||
)
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.utils import timezone
|
|
||||||
from django.core.mail import send_mail
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
USERNAME_REQUIRED = settings.DJOK_USER_TYPE == "username"
|
|
||||||
EMAIL_REQUIRED = settings.DJOK_USER_TYPE.startswith("email")
|
|
||||||
if not (USERNAME_REQUIRED or EMAIL_REQUIRED):
|
|
||||||
raise ValueError("Must set DJOK_USER_TYPE")
|
|
||||||
|
|
||||||
|
|
||||||
class OkUserManager(UserManager):
|
|
||||||
def create_superuser(self, **kwargs):
|
|
||||||
if "username" not in kwargs:
|
|
||||||
kwargs["username"] = kwargs["email"]
|
|
||||||
super().create_superuser(**kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser, PermissionsMixin):
|
|
||||||
"""
|
|
||||||
A modification of the built-in Django user that:
|
|
||||||
- switches first_name & last_name for username & full_name
|
|
||||||
- keeps other admin-compliant options
|
|
||||||
"""
|
|
||||||
|
|
||||||
username_validator = UnicodeUsernameValidator()
|
|
||||||
|
|
||||||
email = models.EmailField(_("email address"), unique=EMAIL_REQUIRED, default="")
|
|
||||||
username = models.CharField(
|
|
||||||
max_length=255,
|
|
||||||
unique=True,
|
|
||||||
validators=[username_validator] if USERNAME_REQUIRED else [],
|
|
||||||
default="",
|
|
||||||
)
|
|
||||||
full_name = models.CharField(_("full name"), max_length=150, blank=True)
|
|
||||||
is_staff = models.BooleanField(
|
|
||||||
_("staff status"),
|
|
||||||
default=False,
|
|
||||||
help_text=_("Designates whether the user can log into this admin site."),
|
|
||||||
)
|
|
||||||
is_active = models.BooleanField(
|
|
||||||
_("active"),
|
|
||||||
default=True,
|
|
||||||
help_text=_(
|
|
||||||
"Designates whether this user should be treated as active. "
|
|
||||||
"Unselect this instead of deleting accounts."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
|
|
||||||
|
|
||||||
objects = OkUserManager()
|
|
||||||
|
|
||||||
EMAIL_FIELD = "email"
|
|
||||||
USERNAME_FIELD = "username" if USERNAME_REQUIRED else "email"
|
|
||||||
REQUIRED_FIELDS = []
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _("user")
|
|
||||||
verbose_name_plural = _("users")
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
super().clean()
|
|
||||||
self.email = self.__class__.objects.normalize_email(self.email)
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if EMAIL_REQUIRED and not self.username:
|
|
||||||
self.username = self.email
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_short_name(self):
|
|
||||||
return self.username
|
|
||||||
|
|
||||||
def get_full_name(self):
|
|
||||||
return self.full_name
|
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None, **kwargs):
|
|
||||||
send_mail(subject, message, from_email, [self.email], **kwargs)
|
|
@ -65,11 +65,8 @@ INSTALLED_APPS = [
|
|||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"allauth",
|
"allauth",
|
||||||
"allauth.account",
|
"allauth.account",
|
||||||
# Uncomment for MFA/Webauthn
|
|
||||||
# "allauth.mfa",
|
|
||||||
"django_structlog",
|
"django_structlog",
|
||||||
"django_typer",
|
"django_typer",
|
||||||
"apps.accounts",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -119,8 +116,6 @@ USE_TZ = True
|
|||||||
|
|
||||||
# Authentication -----
|
# Authentication -----
|
||||||
|
|
||||||
AUTH_USER_MODEL = "accounts.User"
|
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
AUTHENTICATION_BACKENDS = [
|
||||||
"django.contrib.auth.backends.ModelBackend",
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
"allauth.account.auth_backends.AuthenticationBackend",
|
"allauth.account.auth_backends.AuthenticationBackend",
|
||||||
@ -141,24 +136,21 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
# DJOK_USER_TYPE is a setting we introduce to pick between
|
DJOK_AUTH_MODE = "username"
|
||||||
|
# DJOK_AUTH_MODE is a setting we introduce to pick between
|
||||||
# a few common auth patterns.
|
# a few common auth patterns.
|
||||||
#
|
#
|
||||||
# It is also used in accounts/models.py.
|
# Things other than 'username' currently experimental.
|
||||||
#
|
#
|
||||||
# WARNING: Changing this setting after initial setup can have
|
# 'username'
|
||||||
# data-loss consequences.
|
# A username-based email
|
||||||
|
#
|
||||||
|
# 'email'
|
||||||
|
# This configures django-allauth with reasonably secure defaults
|
||||||
|
# for an email-based account.
|
||||||
|
#
|
||||||
|
# ''
|
||||||
#
|
#
|
||||||
# See documentation for explanation of options.
|
|
||||||
DJOK_USER_TYPE = "email"
|
|
||||||
# DJOK_PASSWORD_PROMPTS determines how many password prompts are shown.
|
|
||||||
# 0 - Email/Token based login.
|
|
||||||
# 1 - Single password box.
|
|
||||||
# 2 - Password box with confirmation.
|
|
||||||
DJOK_PASSWORD_PROMPTS = 0
|
|
||||||
|
|
||||||
_PASSWORDS = {0: [], 1: ["password1*"], 2: ["password1*", "password2*"]}[DJOK_PASSWORD_PROMPTS]
|
|
||||||
|
|
||||||
ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False
|
ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False
|
||||||
ACCOUNT_PRESERVE_USERNAME_CASING = False
|
ACCOUNT_PRESERVE_USERNAME_CASING = False
|
||||||
ACCOUNT_LOGIN_BY_CODE_ENABLED = True
|
ACCOUNT_LOGIN_BY_CODE_ENABLED = True
|
||||||
@ -170,24 +162,17 @@ ACCOUNT_USERNAME_BLACKLIST = ["admin"]
|
|||||||
# ACCOUNT_LOGIN_BY_CODE_REQUIRED = False
|
# ACCOUNT_LOGIN_BY_CODE_REQUIRED = False
|
||||||
# ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
|
# ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
|
||||||
|
|
||||||
if DJOK_USER_TYPE in ("email", "email+username"):
|
if DJOK_AUTH_MODE == "email":
|
||||||
|
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
|
||||||
ACCOUNT_LOGIN_METHODS = {"email"}
|
ACCOUNT_LOGIN_METHODS = {"email"}
|
||||||
|
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
|
||||||
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
|
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
|
||||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||||
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
|
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
|
||||||
if DJOK_USER_TYPE == "email":
|
else: # "username"
|
||||||
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
|
# ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||||
ACCOUNT_SIGNUP_FIELDS = ["email*"] + _PASSWORDS
|
# ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
|
||||||
else:
|
pass
|
||||||
ACCOUNT_USER_MODEL_USERNAME_FIELD = "username"
|
|
||||||
ACCOUNT_SIGNUP_FIELDS = ["email*", "username"] + _PASSWORDS
|
|
||||||
|
|
||||||
# Uncomment for Webauthnn
|
|
||||||
# MFA_SUPPORTED_TYPES = ["webauthn"]
|
|
||||||
# MFA_PASSKEY_LOGIN_ENABLED = True
|
|
||||||
# MFA_PASSKEY_SIGNUP_ENABLED = True
|
|
||||||
# if DEBUG:
|
|
||||||
# MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True
|
|
||||||
|
|
||||||
|
|
||||||
# Logging Config ---------
|
# Logging Config ---------
|
||||||
|
@ -6,7 +6,7 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"django>=5.2,<6",
|
"django>=5.2,<6",
|
||||||
"django-allauth[mfa]>=65.7.0",
|
"django-allauth>=65.7.0",
|
||||||
"django-debug-toolbar>=5.1.0",
|
"django-debug-toolbar>=5.1.0",
|
||||||
"django-environ>=0.12.0,<1",
|
"django-environ>=0.12.0,<1",
|
||||||
"django-structlog>=9.1.0,<10",
|
"django-structlog>=9.1.0,<10",
|
||||||
|
4
static/css/pico.min.css
vendored
4
static/css/pico.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "allauth/layouts/entrance.html" %}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
{% load static %}
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<meta name="color-scheme" content="light dark">
|
|
||||||
<link rel="stylesheet" href="{% static 'css/pico.min.css' %}">
|
|
||||||
<title>{% block title %}{% endblock %}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<main class="container">
|
|
||||||
{% block content %}
|
|
||||||
{% endblock %}
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
111
uv.lock
generated
111
uv.lock
generated
@ -11,39 +11,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 },
|
{ url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cffi"
|
|
||||||
version = "1.17.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "pycparser" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfgv"
|
name = "cfgv"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
@ -74,41 +41,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cryptography"
|
|
||||||
version = "44.0.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/cd/25/4ce80c78963834b8a9fd1cc1266be5ed8d1840785c0f2e1b73b8d128d505/cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", size = 710807 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/92/ef/83e632cfa801b221570c5f58c0369db6fa6cef7d9ff859feab1aae1a8a0f/cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", size = 6676361 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/30/ec/7ea7c1e4c8fc8329506b46c6c4a52e2f20318425d48e0fe597977c71dbce/cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", size = 3952350 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/61/72e3afdb3c5ac510330feba4fc1faa0fe62e070592d6ad00c40bb69165e5/cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", size = 4166572 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/e4/ba680f0b35ed4a07d87f9e98f3ebccb05091f3bf6b5a478b943253b3bbd5/cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", size = 3958124 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9c/e8/44ae3e68c8b6d1cbc59040288056df2ad7f7f03bbcaca6b503c737ab8e73/cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", size = 3678122 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/27/7b/664ea5e0d1eab511a10e480baf1c5d3e681c7d91718f60e149cec09edf01/cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", size = 4191831 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/07/79554a9c40eb11345e1861f46f845fa71c9e25bf66d132e123d9feb8e7f9/cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", size = 3960583 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bb/6d/858e356a49a4f0b591bd6789d821427de18432212e137290b6d8a817e9bf/cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308", size = 4191753 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/80/62df41ba4916067fa6b125aa8c14d7e9181773f0d5d0bd4dcef580d8b7c6/cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", size = 4079550 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f3/cd/2558cc08f7b1bb40683f99ff4327f8dcfc7de3affc669e9065e14824511b/cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", size = 4298367 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/71/59/94ccc74788945bc3bd4cf355d19867e8057ff5fdbcac781b1ff95b700fb1/cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", size = 2772843 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/2c/0d0bbaf61ba05acb32f0841853cfa33ebb7a9ab3d9ed8bb004bd39f2da6a/cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", size = 3209057 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/be/7a26142e6d0f7683d8a382dd963745e65db895a79a280a30525ec92be890/cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", size = 6677789 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/06/88/638865be7198a84a7713950b1db7343391c6066a20e614f8fa286eb178ed/cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", size = 3951919 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d7/fc/99fe639bcdf58561dfad1faa8a7369d1dc13f20acd78371bb97a01613585/cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", size = 4167812 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/53/7b/aafe60210ec93d5d7f552592a28192e51d3c6b6be449e7fd0a91399b5d07/cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", size = 3958571 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/16/32/051f7ce79ad5a6ef5e26a92b37f172ee2d6e1cce09931646eef8de1e9827/cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", size = 3679832 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/78/2b/999b2a1e1ba2206f2d3bca267d68f350beb2b048a41ea827e08ce7260098/cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", size = 4193719 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/72/97/430e56e39a1356e8e8f10f723211a0e256e11895ef1a135f30d7d40f2540/cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", size = 3960852 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/89/33/c1cf182c152e1d262cac56850939530c05ca6c8d149aa0dcee490b417e99/cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", size = 4193906 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e1/99/87cf26d4f125380dc674233971069bc28d19b07f7755b29861570e513650/cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", size = 4081572 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b3/9f/6a3e0391957cc0c5f84aef9fbdd763035f2b52e998a53f99345e3ac69312/cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", size = 4298631 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e2/a5/5bc097adb4b6d22a24dea53c51f37e480aaec3465285c253098642696423/cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", size = 2773792 },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/33/cf/1f7649b8b9a3543e042d3f348e398a061923ac05b507f3f4d95f11938aa9/cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", size = 3210957 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "distlib"
|
name = "distlib"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -142,12 +74,6 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/08/8557880768ba4d5966195ee5e57c69d8b9425c62ffb80293e2ad36dffb83/django_allauth-65.7.0.tar.gz", hash = "sha256:eb060692150f39e1529893c2de5f9b46e1dab51153ff6cca7ad72c7c125259ea", size = 1640126 }
|
sdist = { url = "https://files.pythonhosted.org/packages/4b/08/8557880768ba4d5966195ee5e57c69d8b9425c62ffb80293e2ad36dffb83/django_allauth-65.7.0.tar.gz", hash = "sha256:eb060692150f39e1529893c2de5f9b46e1dab51153ff6cca7ad72c7c125259ea", size = 1640126 }
|
||||||
|
|
||||||
[package.optional-dependencies]
|
|
||||||
mfa = [
|
|
||||||
{ name = "fido2" },
|
|
||||||
{ name = "qrcode" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-debug-toolbar"
|
name = "django-debug-toolbar"
|
||||||
version = "5.1.0"
|
version = "5.1.0"
|
||||||
@ -218,7 +144,7 @@ version = "0.1.0"
|
|||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "django" },
|
{ name = "django" },
|
||||||
{ name = "django-allauth", extra = ["mfa"] },
|
{ name = "django-allauth" },
|
||||||
{ name = "django-debug-toolbar" },
|
{ name = "django-debug-toolbar" },
|
||||||
{ name = "django-environ" },
|
{ name = "django-environ" },
|
||||||
{ name = "django-structlog" },
|
{ name = "django-structlog" },
|
||||||
@ -233,7 +159,7 @@ dependencies = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "django", specifier = ">=5.2,<6" },
|
{ name = "django", specifier = ">=5.2,<6" },
|
||||||
{ name = "django-allauth", extras = ["mfa"], specifier = ">=65.7.0" },
|
{ name = "django-allauth", specifier = ">=65.7.0" },
|
||||||
{ name = "django-debug-toolbar", specifier = ">=5.1.0" },
|
{ name = "django-debug-toolbar", specifier = ">=5.1.0" },
|
||||||
{ name = "django-environ", specifier = ">=0.12.0,<1" },
|
{ name = "django-environ", specifier = ">=0.12.0,<1" },
|
||||||
{ name = "django-structlog", specifier = ">=9.1.0,<10" },
|
{ name = "django-structlog", specifier = ">=9.1.0,<10" },
|
||||||
@ -245,18 +171,6 @@ requires-dist = [
|
|||||||
{ name = "whitenoise", specifier = ">=6.9.0,<7" },
|
{ name = "whitenoise", specifier = ">=6.9.0,<7" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fido2"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "cryptography" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/eb/cc/4529123364d41f342145f2fd775307eaed817cd22810895dea10e15a4d06/fido2-1.2.0.tar.gz", hash = "sha256:e39f95920122d64283fda5e5581d95a206e704fa42846bfa4662f86aa0d3333b", size = 266369 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4c/48/e9b99d66f27d3416a619324568739fd6603e093b2f79138d6f47ccf727b6/fido2-1.2.0-py3-none-any.whl", hash = "sha256:f7c8ee62e359aa980a45773f9493965bb29ede1b237a9218169dbfe60c80e130", size = 219418 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filelock"
|
name = "filelock"
|
||||||
version = "3.18.0"
|
version = "3.18.0"
|
||||||
@ -357,15 +271,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707 },
|
{ url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pycparser"
|
|
||||||
version = "2.22"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
version = "2.19.1"
|
version = "2.19.1"
|
||||||
@ -437,18 +342,6 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
|
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "qrcode"
|
|
||||||
version = "8.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/61/d4/d222d00f65c81945b55e8f64011c33cb11a2931957ba3e2845fb0874fffe/qrcode-8.1.tar.gz", hash = "sha256:e8df73caf72c3bace3e93d9fa0af5aa78267d4f3f5bc7ab1b208f271605a5e48", size = 41549 }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/29/e6/273de1f5cda537b00bc2947082be747f1d76358db8b945f3a60837bcd0f6/qrcode-8.1-py3-none-any.whl", hash = "sha256:9beba317d793ab8b3838c52af72e603b8ad2599c4e9bbd5c3da37c7dcc13c5cf", size = 45711 },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "14.0.0"
|
version = "14.0.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user